---
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
```