--- title: "Домашнее задание 5" output: pdf_document: default html_document: df_print: paged header-includes: - \usepackage[russian]{babel} - \usepackage{hyperref} - \usepackage{graphics} - \usepackage{amsmath} - \hypersetup{colorlinks = true, urlcolor = blue} --- ## Автоматические тесты Большинство задач в домашнем задании по R предполагают автоматическое тестирование решений. Один тест представляет собой блок кода, который возвращает значение TRUE, если тест пройден, и значение FALSE, если тест не пройден. Если какие-то тесты не пройдены, выводится ошибка вида `[something] не TRUE`. Перед каждым тестом приводятся пояснения, которые помогают понять, что именно не так с решением. 1. Если у вас **успешно** установились библиотеки `devtools` и `testrmd`: ```{r, eval=FALSE} install.packages("devtools") devtools::install_github("ropenscilabs/testrmd") ``` можете убрать опцию `eval=FALSE` в ячейке ниже, связывать Rmd-файл в html и смотреть на выполнение тестов. ```{r, eval=FALSE} testrmd::init() ``` При связывании текущего Rmd-файла в готовом html-файле отображаются включения с информацией о пройденных тестах. Если какие-то тесты не пройдены, рядом с блоком с решением задачи появляется красная кнопка, а в начале файла появляется предупреждение вида `Warning! This document contains N failing tests`. Можно кликнуть на красную кнопку и посмотреть, какие тесты не пройдены и почему. 2. Если библиотеки `devtools` и `testrmd` **не установились**, запускайте строки в ячейке с тестами как обычный код и проверяйте, пройден ли тест. Если после запуска ячейки с тестом не выводится сообщение об ошибке, тест пройден. \newpage ### Задача 1 Напишите функцию `sales_eval()`, которая * принимает на вход два числа: число продаж в прошлом году, число продаж в текущем году; * возвращает и выводит на экран сообщение "This salesperson is successful.", если число продаж в текущем году больше, чем в предыдущем, и сообщение "This salesperson is not successful.", если число продаж в текущем году не больше, чем в предыдущем. **Пример:** ``` > sales_eval(700, 500) [1] "This salesperson is not successful." > sales_eval(700, 1000) [1] "This salesperson is successful." ``` ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` **Тесты:** Если тесты ниже не пройдены, функция возвращает неверный результат. ```{r test_chunk1, test = TRUE} stopifnot(sales_eval(700, 500) == "This salesperson is not successful.", TRUE) stopifnot(sales_eval(700, 700) == "This salesperson is not successful.", TRUE) stopifnot(sales_eval(500, 1500) == "This salesperson is successful.", TRUE) ``` ### Задача 2 Напишите функцию `final_mark()`, которая принимает на вход числовой вектор из двух элементов (накопленная оценка и оценка за экзамен) и возвращает итоговую оценку, округленную до целого значения, посчитанную по следующей формуле: $$ \text{Итог} = 0.6 \times \text{накопленная} + 0.4 \times \text{экзамен}. $$ **Пример:** ``` > final_mark(c(7, 8)) [1] 7 ``` ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` **Тесты:** Если тесты ниже не пройдены, функция возвращает неверный результат. ```{r test_chunk2, test = TRUE} stopifnot(final_mark(c(9, 0)) == 5, TRUE) stopifnot(final_mark(c(7, 6)) == 7, TRUE) stopifnot(final_mark(c(7, 8)) == 7, TRUE) stopifnot(final_mark(c(2, 4)) == 3, TRUE) ``` ### Задача 3 Напишите функцию `assess_sleep()`, которая принимает на вход число часов, которое пользователь спал в среднем за неделю и: * если значение менее 3, возвращает и выводит на экран сообщение "Alarm! Are you still alive?"; * если не менее 3 и менее 5, сообщение "Well. Maybe you will survive."; * не менее 5 — сообщение "You can live, I believe." **Пример:** ``` > assess_sleep(2) [1] "Alarm! Are you still alive?" > assess_sleep(7) [1] "You can live, I believe." ``` ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` **Тесты:** Если тесты ниже не пройдены, функция возвращает неверный результат. ```{r test_chunk3, test = TRUE} stopifnot(assess_sleep(2) == "Alarm! Are you still alive?", TRUE) stopifnot(assess_sleep(3) == "Well. Maybe you will survive.", TRUE) stopifnot(assess_sleep(4) == "Well. Maybe you will survive.", TRUE) stopifnot(assess_sleep(5) == "You can live, I believe.", TRUE) stopifnot(assess_sleep(6) == "You can live, I believe.", TRUE) ``` ### Задача 4 Напишите функцию `outliers_ind()`, которая принимает на вход числовой вектор и возвращает индексы нетипичных значений. Готовые функции R для определения нетипичных значений использовать нельзя и вытаскивать их из `boxplot()` тоже. **Подсказка:** границы типичных значений определяются как $$ [\text{Q1} - 1.5 \times \text{IQ};~\text{Q3} + 1.5 \times \text{IQ}], $$ где * $\text{Q1}$ — нижний квартиль, квантиль уровня 0.25; получить можно с помощью `quantile(my_vector, prob = 0.25)`; * $\text{Q3}$ — верхний квартиль, квантиль уровня 0.75; получить можно с помощью `quantile(my_vector, prob = 0.75)`; * $\text{IQ}$ — межквартильный размах, вычисляется как `Q3 - Q1` Соответственно, нетипичные значения — все те, которые меньше нижней границы типичных значений или которые больше верхней границы типичных значений. ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` **Тесты:** Если тесты ниже не пройдены, функция возвращает неверный результат. ```{r test_chunk4, test = TRUE} stopifnot(outliers_ind(c(5, 6, -1, -100, 8, 9)) == 4, TRUE) stopifnot(outliers_ind(c(9, 12, 16, 27, -19, 200, -100)) == c(6, 7), TRUE) stopifnot(outliers_ind(c(90, 12, 16, 27, -19, 200, -100)) == c(6, 7), TRUE) stopifnot(outliers_ind(c(900, 12, 16, 27, -19, 200, -100)) == 1, TRUE) ``` ### Задача 5 Напишите функцию `get_info()`, которая принимает на вход датафрейм и возвращает список (*list*) из следующих векторов: * вектор `dimensions` — содержит 2 элемента: число строк и столбцов в базе данных * вектор `columns` — содержит названия столбцов в базе данных * вектор `rows.na` — содержит номера строк, содержащих пропущенные значения **Пример:** ``` > data A B C 1 18 0 1 2 22 1 4 3 33 0 7 4 19 1 NA 5 45 0 9 6 NA 1 0 7 48 0 0 8 NA 1 1 > get_info(data) $dimensions [1] 8 3 $columns [1] "A" "B" "C" $rows.na [1] 4 6 8 ``` ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` **Тесты:** Если тесты ниже не пройдены, функция возвращает неверный результат. ```{r test_chunk5, test = TRUE} stopifnot(get_info(beaver1)$dimensions == c(114, 4), TRUE) stopifnot(get_info(beaver1)$columns == c("day", "time", "temp", "activ"), TRUE) stopifnot(get_info(beaver1)$rows.na == integer(0), TRUE) ff <- cbind.data.frame(A = c(2, 4, NA), B = c(NA, 6, 9), C = c(1, 0, 1)) stopifnot(get_info(ff)$dimensions == c(3, 3), TRUE) stopifnot(get_info(ff)$columns == c("A", "B", "C"), TRUE) stopifnot(get_info(ff)$rows.na == c(1, 3), TRUE) ``` ### Задача 6 Напишите функцию `dante()`, которая выводит на экран вопрос «В каком кругу Ада по Данте находится Платон?», сохраняет ответ пользователя, введенный с клавиатуры, и, если ответ верный (принимаются ответы `Лимб`, `первый` и `1`), то возвращает и выводит на экран сообщение "Верный ответ!", если нет — выводит сообщение "Неверно. Перечитайте Данте!". **Пример:** ``` > dante() В каком кругу Ада по Данте находится Платон? 1 [1] "Верный ответ!" > dante() В каком кругу Ада по Данте находится Платон? Лимб [1] "Верный ответ!" > dante() В каком кругу Ада по Данте находится Платон? второй [1] "Неверно. Перечитайте Данте!" ``` ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ``` ### Задача 7 Напишите функцию `motivate()`, которая запрашивает у пользователя с клавиатуры некоторый текст и работает следующим образом: ``` Enter your word(s): курсач [1] "Every night in my dreams, I see you, курсач." [1] "Great! You backed the right horse!" Enter your word(s): Курсач [1] "Every night in my dreams, I see you, Курсач." [1] "Great! You backed the right horse!" Enter your word(s): КУРСАЧ [1] "Every night in my dreams, I see you, КУРСАЧ." [1] "Great! You backed the right horse!" Enter your word(s): кот [1] "Every night in my dreams, I see you, кот." [1] "В смысле не курсач?" ``` Другими словами, функция возвращает и выводит на экран сообщения одного вида, если пользователь ввел слово «курсач» в разных регистрах (курсач, Курсач, КУРСАЧ) и сообщения другого вида, если пользователь ввел что-то иное. ```{r} ###BEGIN YOUR CODE ###END YOUR CODE ```