|
Вспомогательные функции задачника
Поддержка языка Python была добавлена в версии 4.11 электронного задачника, а языка R в версии 4.25.
Набор вспомогательных функций для языка Python был дополнен в версиях 4.19 и 4.25.
Описанные на данной странице функции и класс Node будут доступны в программе, если к ней подключен модуль
pt4.py для языка Python или модуль PT4.R для языка R (данные модули входят в состав дистрибутива задачника Programming Taskbook и автоматически
подключаются к любому проекту-заготовке, созданному для выполнения задания на языках Python и R).
Функции для языка Python имеют имена, состоящие из строчных букв, в соответствии с традиционным именованием функций в данном языке.
Аналогичные функции для языка R имеют имена, начинающиеся с заглавной буквы, чтобы избежать конфликта с именами стандартных функций этого языка.
При описании функций используются имена для языка Python, однако эти описания соответствуют и одноименным функциям языка R, если особо не указаны
имеющиеся отличия.
Инициализация заданий, ввод-вывод данных
[Python]
task(name)
[R]
Task(name)
Функция инициализирует задание с именем name (обязательный строковый параметр). Она должна
вызываться в начале программы, выполняющей это задание (до вызова функций ввода-вывода get и put).
Если в программе, подключившей модуль pt4, не указана функция task, то при запуске программы
в окне интерпретатора Python или R будет выведено сообщение «Не вызвана функция 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,
используя его контекстное меню).
[Python]
get()
get_bool()
get_int()
get_float()
get_str()
get_Node()
[R]
Get()
Функции обеспечивают ввод исходных данных в программу, выполняющую учебное задание. Они должны вызываться
после вызова функции task; в случае их вызова до функции task программа выведет сообщение об ошибке
«В начале программы не вызвана функция task с именем задания».
Каждый вызов функции возвращает очередной
элемент исходных данных. Функция get/Get позволяет ввести элемент (вектор длины 1 в случае языка R)
данных любого типа (логического bool/logical, целого int/integer,
вещественного float/double, строкового str/character или особого типа Node, определенного в задачнике и описываемого ниже).
Исходные данные символьного типа также вводятся как строки.
Для языка Python также предусмотрены особые функции для ввода даннных определенного типа:
get_bool логического, get_int целого, get_float вещественного, get_str строкового,
get_Node объекта типа Node
(символы в языке Python не являются особым типом данных, поэтому для них не предусмотрено
специальной функции ввода).
Особенность «специализированных»
функций get_bool, get_int, get_float, get_str и get_Node по сравнению с «универсальной»
функцией get состоит в том, что если
вызванная «специализированная» функция не соответствует типу очередного элемента исходных данных, то
выводится сообщение об ошибке «Неверно указан тип при вводе исходных данных»
(такое сообщение будет выведено, например, если очередной элемент данных является символом,
а для его ввода используется функция get_int). Таким образом, применение «специализированных»
функций позволяет задачнику выявить такие ошибки ввода, как, например,
ошибки, связанные с неверным порядком чтения исходных данных. «Универсальная»
функция get больше соответствует идеологии языка Python, однако при ее использовании
теряется часть возможностей задачника, связанных с контролем правильности ввода исходных данных.
При попытке ввести больше исходных данных, чем это предусмотрено в задании, выводится сообщение
об ошибке «Попытка ввести лишние исходные данные». Если исходные данные, необходимые
для решения задания, введены не полностью, то выводится сообщение «Введены не все требуемые исходные данные».
[Python]
get2()
get3()
get4()
get5()
get_list(n = -1)
get_matr(m = -1, n = -1)
Указанные функции появились в версии задачника 4.19. Они упрощают организацию ввода нескольких скалярных данных, а также
наборов данных, которые следует сохранять в списке или в матрице (списке списков).
Функции get2, get3, get4, get5 обеспечивают последовательный вызов 2, 3, 4 и 5 функций get и возвращают
кортеж, содержащий все введенные данные. Например, для ввода трех исходных данных и записи их в переменные a, b, c
достаточно использовать оператор
[Python]
a, b, c = get3()
Функция get_list без параметров вначале считывает размер n вводимого списка (с помощью функции get_int), после чего
считывает n последующих элементов исходных данных (с помощью функции get) и добавляет их в список,
который возвращается как результат работы этой функции.
Если при вызове функции get_list явно указан неотрицательный целочисленный параметр n, то он считается размером списка;
в этом случае функция вводит только элементы списка. Отрицательные значения параметра n означают, что перед вводом
элементов необходимо ввести размер списка (таким образом, в случае отрицательного параметра функция ведет себя так же,
как при вызове без параметров). Если параметр не является целым числом, то возбуждается исключение.
Функция get_matr без параметров вначале считывает размеры m и n вводимой матрицы
(с помощью двух функций get_int), после чего
считывает m*n последующих элементов исходных данных (с помощью функции get) и добавляет их в список,
который возвращается как результат работы этой функции. Предполагается, что значение m определяет число строк и соответствует
первому индексу полученной матрицы, а значение n определяет число столбцов и соответствует второму индексу матрицы.
Предполагается также, что ввод элементов матрицы осуществляется по строкам. Результирующая матрица представляет собой
список списков. Таким образом, оператор a = get_matr() эквивалентен следующей последовательности операторов:
[Python]
m, n = get_int(), get_int()
a = [[get() for j in range(n)] for i in range(m)]
Если при вызове функции get_matr явно указаны два неотрицательных целочисленных параметра m и n,
то они считаются размерами матрицы; в этом случае функция вводит только элементы матрицы.
Если второй параметр (n) не указан или является отрицательным, а первый параметр (m) указан и является неотрицательным,
то считается, что вводимая матрица является квадратной матрицей порядка m; в этом случае функция также вводит только
элементы матрицы. Таким образом, для ввода квадратной матрицы (в предположении, что перед ее элементами задается
единственное значение порядок матрицы) достаточно выполнить следующий оператор:
[Python]
a = get_matr(get())
Если первый параметр функции get_matr является отрицательным, то функция работает так же,
как при вызове без параметров.
Если параметры функции не являются целыми, то возбуждается исключение.
[Python]
get_array(n = -1)
get_array2(m = -1, n = -1)
[R]
GetV(len = 0)
GetM(nrow = 0, ncol = 0)
Указанные функции для языка Python появились в версии задачника 4.25. Они позволяют сохранять наборы однотипных данных в
одномерных или двумерных массивах NumPy. Эти функции можно вызывать только после установки модуля NumPy.
Если для используемой версии Python модуль NumPy не установлен, то выводится сообщение об ошибке «the NumPy module is not available»
(сообщение на английском языке означает, что данная ошибка обнаружена без обращения к ядру задачника).
Функция get_array позволяет сохранять исходные данные в одномерном массиве, функция get_array2 в двумерном массиве.
Параметр n для функции get_array имеет тот же смысл, что и параметр n для функции get_list.
Параметры m и n для функции get_array2 имеют тот же смысл, что и параметры m и n для функции get_matr.
Функции GetV и GetM для языка R ведут себя аналогично функциям get_list (get_array) и get_matr (get_array2) языка Python.
Функция GetV без параметров вначале читает целое число, определяющее размер вектора, а затем элементы вектора, после чего возвращает полученный вектор.
Такое поведение соответствует значению параметра len по умолчанию, равному 0.
Вариант этой функции с одним положительным параметром len (GetV(len)) не считывает размер вектора, а сразу вводит len его элементов.
При указании отрицательного параметра или параметра, имеющего дробную часть, или параметра, не являющегося числом, выводится сообщение об ошибке.
Тип элементов вектора определяется по типу первого прочитанного элемента.
Функция GetM без параметров вначале читает два целых числа, определяющих размер матрицы (вначале число строк, затем число столбцов),
затем считывает элементы матрицы, после чего возвращает полученную матрицу. Такое поведение соответствует значениям параметров nrow и ncol, равным 0.
Вариант этой функции с одним положительным параметром, равным m (GetM(m) или GetM(nrow = m) или GetM(ncol = m)) не считывает размеры матрицы,
а сразу вводит ее элементы, предполагая, что матрица является квадратной матрицей порядка m. Вариант функции с двумя положительными параметрами
nrow и ncol также не считывает размеры матрицы, а сразу вводит ее элементы, предполагая, что матрица является прямоугольной матрицей
размера nrow на ncol. При указании отрицательных параметров или параметров, имеющих дробную часть, или параметров, не являющихся числами,
выводится сообщение об ошибке. Тип элементов матрицы определяется по типу первого прочитанного элемента. Ввод элементов всегда осуществляется по строкам.
[Python]
put(a, ...)
[R]
Put(...)
Функция put обеспечивает вывод на экран результирующих данных, найденных программой,
и их сравнение с контрольными данными (т. е. с правильным решением). Как и функции группы get,
эта функция должна вызываться после вызова функции task; в противном случае ее вызов приводит к сообщению об ошибке
«В начале программы не вызвана функция task с именем задания».
В функции put можно указывать один или более параметров.
Для языка Python в качестве любого параметра можно указать
выражение типа bool, int, float, str, Node, а также кортеж (tuple) или список (list) элементов этих типов, а также константу None (пустой объект).
Указание кортежа или списка приводит к тому, что в задачник последовательно пересылаются все элементы
этого кортежа или списка. Начиная с версии 4.25, при выводе можно указывать массивы модуля NumPy (любой размерности), а также наборы данных Series
и DataFrame модуля Pandas; в этом случае выводятся все элементы данных наборов. При выводе массивов NumPy элементы перебираются таким образом,
чтобы быстрее изменялись правые индексы (таким образом, для двумерных массивов вывод осуществляется по строкам);
также по строкам выполняется вывод элементов таблиц DataFrame.
Для языка R в качестве любого параметра можно указать
выражение типа logical, integer, double, character, Node (в частности, векторы, матрицы, массивы (arrays) факторы (factors),
списки (lists) и таблицы (data frames) с элементами указанных типов), а также константу NULL (пустой объект).
Задачнику передаются на проверку только элементы наборов данных, без дополнительных атрибутов.
При выводе матрицы или таблицы ее элементы пересылаются задачнику по строкам. При выводе массива большей размерности он интерпретируется как одномерный вектор.
При попытке вывода значений NA, NaN, Inf или -Inf выводится сообщение об ошибке.
При выводе строго контролируется тип выводимых данных; в частности, вещественные числа с нулевой дробной частью не считаются целыми.
Заметим, что пустые объекты, как и объекты типа Node, требуется
выводить только в заданиях групп Dynamic
и Tree и их аналогов GCDyn и GCTree.
В случае языка Python при попытке указания данных других типов
программа генерирует стандартное исключение ValueError с сообщением об ошибке
«the put function has an argument of invalid type».
Тип параметра должен не только быть допустимым, но и соответствовать типу
очередного элемента результирующих данных; в противном случае выводится
сообщение об ошибке «Неверно указан тип при выводе результатов».
При вызове функции put задачник осуществляет контроль
за соответствием количества требуемых и выведенных результирующих данных. Если программа выведет
недостаточное или избыточное количество результирующих данных, то после проверки этих данных появится сообщение
«Выведены не все результирующие данные» или, соответственно, «Попытка вывести лишние результирующие данные».
[Python]
get_countries()
get_students()
put_len(a)
get_file(filename, colnames, combine = 0)
put_file(dataframe, filename)
[R]
GetCountries()
GetStudents()
PutN(dataframe)
GetF(filename, colnames, combine = 0)
PutF(dataframe, filename)
Указанные специализированные функции предназначены для использования при решении задач из групп TableBase и TableExt.
Для языка Python они доступны, начиная с версии 4.25.
Функции get_countries и get_students позволяют ввести исходные таблицы (data frames) для задач группы TableBase (функция get_countries
возвращает таблицу с данными о странах мира и используется в задачах TableBase110, функция get_students
возвращает таблицу с данными об учащихся и используется в задачах TableBase1130).
Функция PutN(dataframe) для языка R
выполняется аналогично функции Put(nrow(dataframe), dataframe), т. е. вначале выводит число строк таблицы dataframe, а затем
ее элементы; эту функцию удобно использовать в тех задачах группы TableBase, в которых требуется вывести не только полученную таблицу, но и ее размер (число строк).
Функция put_len(a) для языка Python может использоваться не только для параметра a типа DataFrame, но и для других структур данных.
Для списков, кортежей и наборов Series она вначале выводит число элементов структуры, а затем ее элементы. Для массивов NumPy она вначале выводит
их размерность по первому измерению, а затем все их элементы (в частности, для двумерных массивов вначале выводится число строк, а затем все их элементы по строкам).
Для таблиц DataFrames, как и в случае языка R, вначале выводится число строк таблицы, а затем ее элементы.
Функция get_file предназначена для ввода исходных файловых данных в заданиях группы TableExt.
Она считывает табличные данные из файла с именем filename и связывает со столбцами полученной таблицы имена, указанные в параметре colnames
(который может быть кортежем или списком для Python и вектором для R).
Кроме того, она объединяет столбцы с номерами combine и combine+1, если параметр combine не равен 0
(это действие требуется для столбцов с фамилиями и инициалами в задачах TableExt49TableExt70).
Функция put_file сохраняет данные из таблицы dataframe в текстовом файле с именем filename. Каждая строка файла содержит одну строку таблицы,
в которой значения столбцов разделяются пробелами, а вещественные числа отображаются с двумя дробными знаками.
В заготовках ко всем заданиям групп TableBase и TableExt для языков Python и R указанные функции ввода уже вызваны, а их возвращаемые значения (таблицы)
сохранены в переменных, например:
[Python]
d = get_file(get(), ("Code", "Year", "Month", "Len"))
[R]
d = GetF(Get(), c('Code', 'Year', 'Month', 'Len'))
По набору параметров функции get_file можно определить имена столбцов таблицы и их порядок.
Кроме того, в заготовках ко всем заданиям группы TableExt для языков Python и R приводятся комментарии, в которых указывается,
как использовать функцию put_file для вывода результатов, и аналогичные комментарии для функции put_len (PutN для R)
приводятся в заготовках к тем заданиям группы TableBase, в которых эта функция может использоваться.
Класс Node
[Python]
# Конструкторы:
Node(data = 0, next = None, prev = None)
Node.for_tree(data = 0, left = None, right = None, parent = None)
# Свойства (доступны для чтения и для записи):
Data
Next
Prev
Left
Right
Parent
# Метод, освобождающий ресурсы, используемые объектом Node:
dispose()
[R]
# Конструкторы:
Node(Data = 0L, Next = NULL, Prev = NULL)
Node.ForTree(Data = 0L, Left = NULL, Right = NULL, Parent = NULL)
# Свойства (доступны для чтения и для записи):
$Data
$Next
$Prev
$Left
$Right
$Parent
# Функция, освобождающая ресурсы, используемые объектом Node:
Dispose(node)
Класс Node используется в заданиях групп Dynamic
и Tree и их аналогов GCDyn и GCTree. В заданиях на
стеки и очереди (Dynamic1Dynamic28) при работе с объектами типа Node
используются только свойства Data и Next; в заданиях на двусвязные списки
(Dynamic29Dynamic80) используются свойства Data, Next и Prev. В большинстве заданий на
бинарные деревья (группа Tree) используются свойства Data, Left и Right;
в заданиях на обработку бинарных деревьев с обратной связью
(Tree48Tree56 и Tree70Tree71) дополнительно используется свойство Parent.
Варианты конструктора класса Node (в том числе варианты функции Node.for_tree)
позволяют задавать значения требуемых свойств при создании
объекта; прочие свойства инициализируются нулевыми значениями
(числом 0 для свойства Data, пустым объектом None для остальных свойств).
Следует обратить внимание на то, что при завершении работы с объектом node типа Node требуется вызвать
его метод node.dispose() для языка Python или функцию Dispose(node) для языка R, которые освобождают неуправляемые ресурсы,
выделенные для этого объекта (исключение делается только для тех объектов, которые передаются обратно
задачнику в качестве результирующих данных). Если в задании требуется вызвать
метод dispose для некоторых объектов, но этот вызов не выполняется, то при запуске
программы выводится сообщение об ошибке «Не вызван метод dispose для
объекта типа Node». При выполнении заданий групп GCDyn и GCTree, появившихся в версии 4.15,
использовать метод dispose не требуется.
Все исходные и результирующие данные-ссылки в заданиях группы Dynamic
имеют тип Node; их ввод и вывод должен осуществляться с помощью описанных выше функций
get (в случае языка Python можно также использовать функцию get_Node) и put.
Вывод отладочной информации
С помощью описываемых далее средств можно выводить отладочную информацию
непосредственно в окно задачника (в специальный раздел отладки).
Следует заметить, что при использовании языков Python и R имеется и другой способ
вывода отладочной информации, основанный на применении стандартной инструкции print.
Отличие заключается в размещении информации: инструкция print
выводит данные в окне интерпретатора Python или R, тогда как описываемые ниже
средства (функции show и show_line) в окно задачника.
Начиная с версии 4.22, в раздел отладки можно выводить текстовые данные,
содержащие любые символы Юникода.
Поскольку функции show для языков Python и R имеют ряд отличий, для них приводятся
отдельные описания.
[Python]
show(a, ...)
Отображает элемент данных в разделе отладки окна задачника. В качестве параметра a можно указывать элемент данных
любого типа; этот элемент будет автоматически преобразован к своему строковому представлению.
Если текущая экранная строка в разделе отладки уже содержит некоторый текст, то
строка a снабжается начальным пробелом и приписывается к предшествующему тексту,
за исключением случая, когда при таком приписывании размер
полученного текста превысит ширину области данных (равную 80 символам).
В последнем случае вывод строки a осуществляется с начала
следующей экранной строки; если же и в этой ситуации строка a превысит
ширину области данных, то строка a будет выведена на нескольких
экранных строках, причем разрывы текста будут выполняться по
пробельным символам строки a, а при отсутствии пробелов при
достижении очередного фрагмента строки длины, равной 80.
Строковый параметр a может содержать явные команды перехода на новую
экранную строку "\n" .
Начиная с версии 4.14, в функции show можно указывать произвольное количество параметров. Параметрами могут быть
элементы данных любого скалярного типа, а также списки и кортежи (для которых выводятся все входящие в них элементы).
Минимальная ширина поля вывода устанавливается функцией set_width(w),
представление вещественных чисел определяется функцией set_precision(d) (обе функции описываются ниже).
Для остальных типов данных используются их стандартные строковые представления (как и в реализации функции show
для предыдущих версий задачника). Числовые данные выравниваются по правой границе, прочие данные по левой.
В версии 4.19 реализация функции show изменена таким образом, чтобы обеспечивать форматированный вывод
структур данных, в том числе вложенных. При оформлении выводимых структур используются стандартные обозначения,
принятые в языке Python: кортежи (tuple) обрамляются круглыми скобками, списки (list) квадратными,
множества (set) и словари (dict) обрамляются фигурными скобками, ключи (key) и значения (value) элементов
словарей разделяются двоеточием. Кроме того, для обеспечения большей наглядности (хотя и в отступление
от правил языка Python) каждый элемент словаря заключается в круглые скобки. Элементы структур разделяются запятыми
(за исключением элементов, которые сами являются множествами, списками или словарями,
после которых запятая не указывается, поскольку
такие элементы разделяются разрывами строк см. далее).
После вывода любой структуры, имеющей переменное число элементов (т. е. множества, списка или словаря),
выполняется автоматический переход на следующую экранную строку в разделе отладки.
При наличии нескольких вложенных структур уровень их вложенности оформляется с помощью дополнительных отступов.
Ниже приводятся примеры использования функции show для вывода различных структур данных.
Фрагмент программы, обеспечивающий отладочный вывод, имеет следующий вид
(было использовано задание Matrix80, в котором дается вещественная квадратная матрица):
[Python]
task("Matrix80")
show_line("Матрица (список списков) вещественных чисел (width = 5):")
a = get_matr(get())
set_width(5)
show_line(a)
show_line("Словарь строковых кортежей (width = 0):")
b1 = {1:("abc","d","e"), 2:("1","7"), 22:("*","!")}
set_width(0)
show_line(b1)
show_line("Словарь строковых списков (width = 3):")
b2 = {1:["abc","d","e"], 2:["1","7"], 22:["*","!"]}
set_width(3)
show_line(b2)
show_line("Список списков, содержащих числовые кортежи (width = 2):")
c1 = [[(1,2,3),(4,5,6)], [(7,8,9),(10,11,12)], [(13,14,15), (16,17,18)]]
set_width(2)
show_line(c1)
show_line("Список списков, содержащих числовые списки (width = 2):")
с2 = [[[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]], [[13,14,15], [16,17,18]]]
show_line(с2)
В приведенном далее образце содержимого раздела отладки следует обратить
внимание на то, что при выводе скалярных элементов или элементов-кортежей
они разделяются запятыми, тогда как после каждого элемента-списка
выполняется переход на новую строку. Кроме того, следует обратить внимание
на использование отступов при выводе многомерных списков, а также на
настройку ширины области вывода с помощью функции set_width.
1> Матрица (список списков) вещественных чисел (width = 5):
2> [ [ 0.49 , 6.30 ]
3> [ 7.31 , 8.43 ]
4> ]
5> Словарь строковых кортежей (width = 0):
6> { ( 1 : ( "abc" , "d" , "e" ) ) , ( 2 : ( "1" , "7" ) ) , ( 22 : ( "*" , "!" ) )
7> }
8> Словарь строковых списков (width = 3):
9> { ( 1 : [ "abc" , "d" , "e" ]
10> ) ( 2 : [ "1" , "7" ]
11> ) ( 22 : [ "*" , "!" ]
12> ) }
13> Список списков, содержащих числовые кортежи (width = 2):
14> [ [ ( 1 , 2 , 3 ) , ( 4 , 5 , 6 ) ]
15> [ ( 7 , 8 , 9 ) , ( 10 , 11 , 12 ) ]
16> [ ( 13 , 14 , 15 ) , ( 16 , 17 , 18 ) ]
17> ]
18> Список списков, содержащих числовые списки (width = 2):
19> [ [ [ 1 , 2 , 3 ]
20> [ 4 , 5 , 6 ]
21> ]
22> [ [ 7 , 8 , 9 ]
23> [ 10 , 11 , 12 ]
24> ]
25> [ [ 13 , 14 , 15 ]
26> [ 16 , 17 , 18 ]
27> ]
28> ]
Данный пример соответствует версии 4.25, в которой строковые данные, входящие в состав
структур, автоматически заключаются в кавычки
(см. также описание функций show_s и show_line_s).
В версии 4.25 в функцию show добавлена возможность вывода массивов NumPy, а также структур Series и DataFrame
модуля Pandas. Ниже приводится фрагмент программы, иллюстрирующий особенности вывода массивов NumPy:
[Python]
task("Matrix58")
show("Двумерный массив вещественных чисел:")
a = get_array2()
show(a)
b = a.reshape(-1)
show_line("Одномерный массив вещественных чисел:")
show_line(b)
c = a.reshape(2, 2, -1)
show_line("Трехмерный массив вещественных чисел:")
show_line(c)
if a.size >= 16:
show_line("Четырехмерный массив вещественных чисел:")
d = a.reshape(2, 2, 2, -1)
show_line(d)
В примере использовано задание Matrix58, по условию которого исходная матрица имеет четное количество строк и столбцов.
Полученные массивы различных размерностей будут выведены в раздел отладки следующим образом:
1> Двумерный массив вещественных чисел:
2> [ array(4,6)
3> 4.94 5.50 8.81 4.24 5.06 4.81 ,
4> 4.37 3.32 8.22 0.57 2.61 1.53 ,
5> 6.56 5.01 8.62 8.88 2.50 3.64 ,
6> 4.85 0.39 3.23 6.03 8.45 6.93 ]
7> Одномерный массив вещественных чисел:
8> [ array(24) 4.94 5.50 8.81 4.24 5.06 4.81 4.37 3.32 8.22 0.57 2.61 1.53 6.56
9> 5.01 8.62 8.88 2.50 3.64 4.85 0.39 3.23 6.03 8.45 6.93 ]
10> Трехмерный массив вещественных чисел:
11> [ array(2,2,6) 4.94 5.50 8.81 4.24 5.06 4.81 , 4.37 3.32 8.22 0.57 2.61 1.53 ;
12> 6.56 5.01 8.62 8.88 2.50 3.64 , 4.85 0.39 3.23 6.03 8.45 6.93 ]
13> Четырехмерный массив вещественных чисел:
14> [ array(2,2,2,3) 4.94 5.50 8.81 , 4.24 5.06 4.81 ; 4.37 3.32 8.22 , 0.57 2.61
15> 1.53 . 6.56 5.01 8.62 , 8.88 2.50 3.64 ; 4.85 0.39 3.23 , 6.03 8.45 6.93 ]
Как и для обычных списков, элементы массивов заключаются в квадратные скобки.
Дополнительно, сразу после открывающей квадратной скобки, указывается текст «аrray»
и, в скобках размерность массива по каждому измерению (кортеж shape).
В отличие от списков, между элементами одномерных массивов не указываются запятые.
Аналогичным образом, запятые не указываются между элементами строк двумерных массивов
и теми элементами трехмерных и четырехмерных массивов, которые отличаются только последним индексом.
Двумерные массивы отображаются в виде матриц, причем автоматически выполняется
выравнивание элементов по столбцам. Для большей наглядности каждая строка матрицы завершается запятой.
При выводе двумерного массива выполняется автоматический переход на новую строку, такой же переход
выполняется и при завершения вывода (обратите внимание на использование функций show, связанных с выводом
двумерного массива в приведенном выше фрагменте).
Массивы с числом размерностей, отличным от 2, выводятся в виде одной строки.
При этом в случае трехмерных и четырехмерных массивов между
наборами элементов с одинаковым предпоследним индексом указываются точки с запятой,
а для четырехмерных массивов дополнительно указываются точки между наборами элементов
с одинаковым третьим с конца индексом. Это упрощает восприятие структуры многомерных массивов.
Например, в приведенном выше фрагменте трехмерный массив можно интерпретировать как две матрицы размера 2 на 6,
причем вначале выводятся две строки первой матрицы (символом ","),
а затем, после разделителя ";", две строки второй матрицы.
Для массивов с числом размерностей, большим 4, как и для одномерных массивов, дополнительные разделители
между элементами не указываются.
В качестве примера отладочного вывода структур Series и DataFrame ниже приводится фрагмент кода для задачи TablBase11:
[Python]
task("TablBase11")
a = get_students()[:6]
show_line("Таблица DataFrame:")
show_line(a)
show_line("Структура Series со строковыми элементами (столбец DataFrame):")
show_line(a.Name)
show_line("Структура Series со числовыми элементами:")
show_line(a.Height)
show_line("Структура Series с элементами категориального типа:")
show_line(a.Gender)
show_line("Структура Series с элементами различных типов (строка таблицы DataFrame):")
show_line(a.iloc[0,:])
show_line("Однострочная таблица DataFrame:")
show_line(a.iloc[0:1,:])
Для уменьшения размеров таблицы, введенной с помощью функции get_students,
к ней сразу применяется срез, возвращающий шесть начальных строк (с индексами от 0 до 5):
1> Таблица DataFrame:
2> 6,5 Name Gender Height Class DevClub
3> [0] "Aleksandrov" Male 162 8 True
4> [1] "Alekseeva" Female 163 7 False
5> [2] "Baranov" Male 171 7 True
6> [3] "Belkin" Male 165 9 True
7> [4] "Belousova" Female 172 10 False
8> [5] "Belyaeva" Female 154 6 False
9> Структура Series со строковыми элементами (столбец DataFrame):
10> [ Series(Name,6) [0] "Aleksandrov" [1] "Alekseeva" [2] "Baranov" [3] "Belkin"
11> [4] "Belousova" [5] "Belyaeva" ]
12> Структура Series со числовыми элементами:
13> [ Series(Height,6) [0] 162 [1] 163 [2] 171 [3] 165 [4] 172 [5] 154 ]
14> Структура Series с элементами категориального типа:
15> [ Series(Gender,6,categories:Female,Male) [0] Male [1] Female [2] Male [3] Male
16> [4] Female [5] Female ]
17> Структура Series с элементами различных типов (строка таблицы DataFrame):
18> [ Series([0],5) ["Name"] "Aleksandrov" ["Gender"] "Male" ["Height"] 162
19> ["Class"] 8 ["DevClub"] True ]
20> Однострочная таблица DataFrame:
21> 1,5 Name Gender Height Class DevClub
22> [0] "Aleksandrov" Male 162 8 True
В приведенном примере использована таблица с 5 столбцами, среди которых имеются столбцы со строковыми (Name),
числовыми (Height и Class), логическими (DevClub) и категориальными (Gender) данными. По умолчанию строки таблицы
индексируются числовыми индексами, а столбцы снабжаются строковыми именами. В левой верхней части таблицы указывается ее размер:
число строк и столбцов. Столбцы таблицы автоматически выравниваются, причем строковые и категориальные данные выравниваются по левой границе,
а числовые и логические данные по правой. Категориальные данные, в отличие от строковых, не заключаются в кавычки. Ширину столбцов таблицы
можно увеличить, используя функцию set_width_df.
Перед выводом таблицы DataFrame выполняется автоматический переход на новую экранную строку (если на предыдущей строке содержится какой-либо текст),
после вывода таблицы также автоматически выполняется переход на новую экранную строку.
Структуру Series можно создать непосредственно или получить из какого-либо столбца таблицы DataFrame. При ее выводе в разделе отладки
вначале указывается открывающая квадратная скобка, затем слово «Series», после которого в скобках указываются некоторые характеристики структуры,
а затем выводятся элементы структуры, причем перед каждым элементом выводится его индекс в квадратных скобках. В конце вывода структуры Series
указывается закрывающая квадратная скобка. В качестве характеристик структуры всегда указывается ее размер, перед которым может указываться имя структуры
(свойство name), а после список категорий, если структура содержит категориальные данные. Перед списком категорий указывается текст «categories»;
если категории являются упорядоченными, то между ними указывается не запятая, а знак "<". Структура Series может содержать данные различного типа;
примером такой структуры является отдельная строка таблицы DataFrame. В приведенном примере подобная структура имеет числовое имя 0 (чтобы подчеркнуть этот
факт, такое имя заключается в квадратные скобки), а ее индексами являются строки имена столбцов. В заключительной части фрагмента кода показано,
как получить отдельную строку исходной таблицы не в виде структуры Series, а в виде однострочной таблицы DataFrame.
В следующем фрагменте кода показано, как создать структуру Series непосредственно из списка, а затем преобразовать ее в структуру Series с категориальными
данными двух видов: с неупорядоченным и упорядоченным набором категорий:
[Python]
a = pd.Series(["Medium", "Low", "High", "Medium"])
c = a.astype("category")
ordered_c = c.cat.set_categories(["Low", "Medium", "High"], ordered=True)
show_line(a)
show_line(c)
show_line(ordered_c)
Полученные структуры будут отображаться в разделе отладки следующим образом:
1> [ Series(4) [0] "Medium" [1] "Low" [2] "High" [3] "Medium" ]
2> [ Series(4,categories:High,Low,Medium) [0] Medium [1] Low [2] High [3] Medium ]
3> [ Series(4,categories:Low<Medium<High) [0] Medium [1] Low [2] High [3] Medium ]
Обратите внимание на следующие особенности: исходная структура не имеет имени, поэтому после слова «Series»
сразу указывается размер структуры; упорядоченные категории разделяются не запятыми, а символами "<"; значения категориальных данных,
в отличие от строковых данных, не заключаются в кавычки.
[R]
Show(...)
Позволяет выводить в раздел отладки любое количество любых данных.
Векторы длины 1 выводятся без каких-либо дополнительных обрамляющих символов; в частности, строки не заключаются в кавычки.
Логические константы выводятся в виде TRUE и FALSE. Вещественные числа по умолчанию выводятся в формате
с фиксированной точкой и двумя дробными знаками. Если выводимая строка содержит символы \n, то каждый из них обеспечивает переход на новую строку в разделе отладки.
Векторы, матрицы и многомерные массивы нулевой длины выводятся в виде пустых квадратных скобок: [ ].
Векторы длины, большей 1, заключаются в квадратные скобки; между их элементами выводятся пробелы.
Непустые матрицы выводятся в виде набора векторов-строк, заключенных в дополнительные квадратные скобки,
причем каждый вектор-строка отображается на отдельной экранной строке,
а после вывода матрицы выполняется автоматический переход на новую экранную строку.
Вывод каждой матрицы автоматически выполняется с начала новой экранной строки.
В качестве примера приведем вывод матрицы, созданной с помощью функции matrix(1:10, nrow= 4, ncol = 3) :
[ [ 1 5 9 ]
[ 2 6 10 ]
[ 3 7 1 ]
[ 4 8 2 ]
]
Этот пример демонстрирует циклическое дополнение элементов матрицы для требуемого размера, а также тот факт,
что по умолчанию созданный набор значений располагается по столбцам (напомним, что для заполнения набора по строкам
в функции matrix достаточно указать параметр byrow = TRUE).
Кроме того, из этого примера видно, что при выводе элементов матрицы выполняется автоматическое выравнивание столбцов.
По умолчанию для вывода каждого элемента используется число позиций, достаточное для вывода самого «широкого» элемента;
кроме того, между элементами добавляется еще один дополнительный пробел.
Непустые многомерные массивы размерности большей двух выводятся в виде обычного одномерного вектора
(полученного путем преобразования исходного многомерного массива с помощью функции as.vector).
Для них внутри квадратных скобок указывается дополнительный текст «array» и информация о размерности (атрибут dim),
а сами элементы отображаются на новой строке. В качестве примера приведем вывод трехмерного массива, созданного
с помощью функции array(1:10, dim = c(2, 3, 4)) :
[ array ( dim: [ 2 3 4 ] )
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 ]
Как и для матриц, перед началом вывода многомерного массива и после его завершения выполняется автоматический переход на новую строку.
При наличии или отсутствии атрибута dim одномерные наборы данных выводятся по-разному
(в виде обычных векторов при отсутствии dim и в виде одномерных массивов при его наличии). Например, при выполнении фрагмента
[R]
a = array(1:10, dim = 10)
Show(a)
a = 1:10
Show(a)
в разделе отладки будет выведен следующий текст:
[ array ( dim: 10 )
1 2 3 4 5 6 7 8 9 10 ]
[ 1 2 3 4 5 6 7 8 9 10 ]
Еще более существенные различия проявятся в случае, если вектор и одномерный массив состоят из одного элемента:
[R]
a = array(10, dim = 1)
Show(a)
a = 10
Show(a)
Результат будет выглядеть следующим образом:
[ array ( dim: 1 ) 10.00 ]
10.00
Многомерный массив, возвращаемый функцией tapply, автоматически снабжается атрибутом dimnames,
играющим важную роль при дальнейшей обработке этого массива. Поэтому при наличии такого атрибута он также отображается в разделе отладки,
причем на отдельной строке (между строкой с информацией об атрибуте dim и строкой с содержимым многомерного массива).
Примеры с атрибутом dimnames приводятся далее.
Функция Show позволяет выводить в наглядном виде в разделе отладки не только векторы, матрицы и массивы,
но и другие стандартные структуры данных языка R. Ниже приведены образцы вывода различных структур.
Списки без дополнительных атрибутов:
{ list $Int: 5 $Dbl: 3.14 $Char: "Example" $Vec: [ 4 5 6 7 ] }
Списки с дополнительными атрибутами, возвращаемые функцией tapply:
{ list ( dim: 7 )
dimnames[[ 1 ]]: [ "5" "6" "7" "8" "9" "10" "11" ]
$5: 10 $6: 7 $7: 7 $8: 5 $9: 7 $10: 12 $11: 5 }
Факторы (неупорядоченные):
[ factor ( levels: Female Male ) Male Male Female Male Female Female ]
Упорядоченные факторы:
[ ordered factor ( levels: Low Medium High ) Medium Low High Medium ]
Таблицы (data frames):
{ $Name $Gender $Height $Class $DevClub
1 "Aleksandrov" Male 162 8 TRUE
2 "Alekseeva" Female 163 7 FALSE
3 "Baranov" Male 171 7 TRUE
4 "Belkin" Male 165 9 TRUE
5 "Belousova" Female 172 10 FALSE
6 "Belyaeva" Female 154 6 FALSE
}
Кроме того, специальный формат предусмотрен для многомерных массивов любой размерности (в том числе матриц),
содержащих дополнительный атрибут dimnames. Такие массивы могут возвращаться функцией tapply.
Приведем примеры отображения массивов размерности 1 и 2 с дополнительными атрибутами:
[ array ( dim: 7 )
dimnames[[ 1 ]]: [ "5" "6" "7" "8" "9" "10" "11" ]
10 7 7 5 7 12 5 ]
[ array ( dim: [ 7 2 ] )
dimnames[[ 1 ]]: [ "5" "6" "7" "8" "9" "10" "11" ]
dimnames[[ 2 ]]: [ "Female" "Male" ]
5 5 1 2 2 6 3 5 2 6 3 5 6 2 ]
[Python]
show_line(a, ...)
[R]
ShowLine(...)
Модификация ранее описанной функции show; после вывода всех указанных элементов данных в раздел отладки
данная функция дополнительно осуществляет автоматический переход на следующую экранную строку.
Может вызываться без параметров, в этом случае просто выполняет переход на следующую строку.
В случае языка R переход на новую строку выполняется только в том случае, если подобный переход
не был выполнен в конце вывода последнего элемента данных (например, матрицы или многомерного массива).
Еще одной особенностью функции ShowLine для языка R является то, что ее вызов без параметров обеспечивает переход на новую экранную строку
только в том случае, если предыдущая строка содержала некоторые данные (таким образом, многократный вызов подряд нескольких функций ShowLine
без параметров не приведет к появлению в разделе отладки пустых строк).
Если требуется добавить в раздел отладки пустые строки, то для этого можно вызвать функцию Show со строковым параметром "\n".
Начиная с версии 4.25, функция show_line для языка Python выполняет дополнительный переход на следующую строку только в случае,
если последним выводимым элементом данных не является многострочная структура (как, например, список списков, двумерный массив, DataFrame),
поскольку после вывода подобных структур всегда выполняется переход на новую строку. Как и для языка R,
вызов функции show_line() без параметров не приводит к переходу на новую строку, если предыдущая экранная строка при этом станет пустой.
[Python]
show_s(a, ...)
show_line_s(a, ...)
[R]
ShowS(...)
ShowLineS(...)
Модификации ранее описанных функций show и show_line, добавленные в версии 4.25.
Выполняются так же, как и функции show и show_line, за исключением того, что все указанные в них строки заключаются
в двойные кавычки и, кроме того, символы "\n" не приводят к переходу на новую экранную строку,
а отображаются в самой строке в виде комбинации \n . Применение данных функций позволяет более наглядно
отобразить в разделе отладки строковые данные, не являющиеся обычными комментариями.
Следует отметить, что при выводе в раздел отладки структур данных, содержащих строки, все строки автоматически заключаются
в кавычки, даже если для вывода этих структур используются функции show или show_line. Таким образом,
необходимость в использовании функций show_s и show_line_s возникает только если в кавычки требуется заключить
отдельные выводимые строки.
[Python]
set_width(w)
set_width_df(wdf)
[R]
SetWidth(w)
SetWidthDF(...)
Функция set_width для языков Python и R задает минимальную ширину w (0 <= w <= 100) поля вывода для элементов
данных, выводимых функциями группы show (за исключением особого элемента "\n" );
по умолчанию минимальная ширина полагается равной 0.
Действие функции распространяется на все последующие вызовы функции show и всех ее модификаций.
Числовые и логические данные выравниваются по правой границе, а строковые данные и категориальные данные (данные-факторы) по левой.
Кроме того, при отображении двумерных массивов в Python и матриц в R предварительно определяется число maxw экранных позиций,
необходимое для вывода самого длинного элемента, и оно используется в качестве ширины поля вывода,
если текущее значение ширины, ранее установленное функцией set_width, меньше, чем maxw.
Для языка R, а начиная с версии 4.25, и для языка Python, предусмотрена функция set_width_df, которая позволяет задать количество экранных позиций,
используемых для вывода столбцов таблиц DataFrame. По умолчанию количество экранных позиций для каждого столбца равно 0,
это означает, что для вывода используется минимально необходимое число позиций, причем это количество будет одинаковым для всех элементов столбца
(в том числе и для его заголовка). Если для вывода элементов столбца недостаточно количества экранных позиций,
установленных функцией set_width_df, то используется минимальное необходимое количество экранных позиций.
В качестве параметра wdf функции set_width_df для языка Python следует указывать кортеж или список с новыми значениями ширины столбцов
(размер параметра wdf может быть как меньше, так и больше числа столбцов).
В случае языка R в качестве параметров функции SetWidthDF можно указывать как отдельные числа (без дробной части), так и векторы из таких чисел.
Сделанные настройки ширины столбцов действуют до очередного вызова функции set_width_df.
[Python]
set_precision(d)
[R]
SetPrecision(d)
Определена в задачнике, начиная с версии 4.14. Позволяет задать формат представления вещественных чисел.
Параметр d должен лежать в диапазоне от -16 до 16.
При d >= 0 числа отображаются в формате с фиксированной точкой и d дробными знаками.
По умолчанию используется формат с d = 2. При d < 0 числа отображаются в экспоненциальном формате с одной цифрой в целой части и -d цифрами в дробной.
Действие функции распространяется на все последующие вызовы функции show и ее модификаций.
[Python]
hide_task()
[R]
HideTask()
Вызов данной функции обеспечивает автоматическое скрытие всех разделов окна
задачника, кроме раздела отладки. Если раздел отладки в окне задачника
не отображается (в частности, если программа запущена в
демонстрационном режиме), то вызов функции hide_task игнорируется.
Игнорируются также все повторные вызовы данной функции.
Скрыть/восстановить основные разделы окна
задачника после его отображения на экране можно также с помощью клавиши
пробела или соответствующей команды контекстного меню раздела отладки.
Дополнительные возможности задачника для языка R, связанные с операцией %>%
Если при решении задач из задачника Programming Taskbook на языке R используется пакет pdlyr,
а для преобразования таблиц (data frames) используются цепочки вызовов функций, объединенных операцией %>%,
то для вывода в раздел отладки промежуточных результатов преобразований
с помощью функций Show, ShowLine, ShowS и ShowLineS можно включать эти функции в цепочку преобразований;
в этом случае они будут выводить полученную таблицу и, при необходимости, другие данные, указанные в списке их параметров, например:
[R]
res = tbl %>%
select(…) %>% Show() %>% # выводится таблица, полученная
# в результате выполнения функции select
filter(…) %>% Show(b, c) %>% # выводится таблица, полученная
# в результате выполнения функции filter,
# а также дополнительные данные b и c
arrange(…)
Функция Show и ее варианты могут использоваться в цепочке вызовов, поскольку все они возвращают свой первый параметр в неизменном виде.
Если в задании требуется вывести полученную таблицу в раздел результатов (или сохранить в файле),
то соответствующую функцию вывода задачника (Put, PutN и PutF) можно указывать в конце цепочки вызовов,
не сохраняя результат преобразований в специальной переменной, например:
[R]
tbl %>%
select(…) %>% Show() %>%
filter(…) %>% Show(b, c) %>%
arrange(…) %>% Show(b, c) %>%
PutF(filename)
В цепочку вызовов можно также помещать специальные варианты функций настройки параметров отладочного вывода:
SetW(data, w) вариант функции SetWidth(w) ,
SetWDF(data, ...) вариант функции SetWidthDF(...) ,
SetP(data, p) вариант функции SetPrecision(p) .
В новых вариантах добавлен «фиктивный» первый параметр data, который не используется, но возвращается этими функциями.
Наличие такого параметра позволяет включать эти варианты функций в цепочки, например:
[R]
tbl %>%
SetW(20) %>% # настраивается ширина поля вывода
SetP(4) %>% # настраивается количество дробных знаков
select(…) %>% Show() %>%
filter(…) %>% Show(b, c) %>%
arrange(…) %>% Show(b, c) %>% PutF(filename)
Таким образом, данные варианты функций настройки ведут себя подобно манипуляторам языка C++ для потоков вывода.
|