Проверка входных данных
Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 55 из 64.
Ввод от пользователей или из файлов является текстом и может содержать что угодно. Проверьте его перед использованием: suppressWarnings(as.numeric(s)) возвращает NA для текста, который не является числом, а is.na() проверяет это:
read_age <- function(s) {
n <- suppressWarnings(as.numeric(s))
if (is.na(n)) return("not a number")
if (n < 0 || n > 130) return("out of range")
paste("age", n)
}
print(read_age("36"))
print(read_age("abc"))
print(read_age("200"))Результат:
[1] "age 36"
[1] "not a number"
[1] "out of range"Валидатор может собрать все проблемы, вместо того чтобы остановиться на первой, что позволяет предоставить более полезную обратную связь. Здесь он возвращает вектор сообщений, который пуст, если входные данные корректны:
check_password <- function(p) {
problems <- c()
if (nchar(p) < 8) problems <- c(problems, "too short")
if (!grepl("[0-9]", p)) problems <- c(problems, "needs a digit")
problems
}
print(check_password("abc"))
print(length(check_password("secret123")))Результат:
[1] "too short" "needs a digit"
[1] 0Выбирайте стиль в зависимости от того, кто вызывает функцию: возвращайте сообщение, когда вызывающий код ожидает некорректный ввод и показывает его пользователю; вызывайте ошибку с помощью stop(), когда некорректный ввод означает ошибку в программе, которая не должна остаться незамеченной.
# вызывающая сторона ожидает некорректный ввод и показывает сообщение
read_age("abc") # "not a number"
# некорректный ввод — это ошибка в программе
if (!is.numeric(x)) stop("x must be numeric")Проверка с помощью tryCatch() вокруг шага разбора позволяет не загромождать основной код проверками: каждая запись либо преобразуется, либо о ней сообщается:
parse_record <- function(line) {
parts <- strsplit(line, ",")[[1]]
if (length(parts) != 2) stop("expected 2 fields")
qty <- suppressWarnings(as.integer(parts[2]))
if (is.na(qty)) stop("quantity is not a whole number")
list(item = parts[1], qty = qty)
}
for (line in c("tea,2", "jam", "oil,x")) {
r <- tryCatch(parse_record(line), error = function(e) conditionMessage(e))
cat(line, ":", if (is.list(r)) paste("ok", r$qty) else r, "\n")
}Вывод:
tea,2 : ok 2
jam : expected 2 fields
oil,x : quantity is not a whole number Задание
ЛегкоЗавершите check_signup(name, age, email). Соберите все проблемы в таком порядке: name is empty (после удаления пробелов в начале и конце), age must be a number, age must be 13 or older (только если возраст является числом) и email needs @. Верните ok, если проблем нет, иначе — проблемы, объединённые с помощью ; .
Предоставленный код считывает имя, возраст и адрес электронной почты (по одному значению в строке) и выводит возвращённое значение.
Попробуйте сами
check_signup <- function(name, age, email) {
# Напишите свой код здесь
"ok"
}
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
cat(check_signup(input[1], input[2], input[3]), sep = "\n")
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и потоки выполнения
1Строки углублённо
Подстроки с substr()Форматирование с sprintf()Разделение и объединениеПоиск в строкахЗамена текстаПовторение — создание имени пользователя4Матрицы
Создание матрицИндексация матрицСводные данные по строкам и столбцамАрифметика матрицПовторение — схема рассадки7Семейство Apply
lapply и sapplyMap и mapplyFilter и FindReduceПовторение — конвейер обработки данных10Продвинутые конструкции управления
Функция switch()Векторизованный ifelse()repeat и breakРекурсивные функцииПовторение — классификатор оценок2Поиск по ключам и значениям
Поиск в именованных векторахПроверка ключейДобавление и удаление ключейПеребор имёнПовторение — биржа акций5Проект — Журнал оценок
Добавление учениковВыставление оценок8Сортировка и группировка
Сортировка векторовСортировка по ключуГруппировка с помощью split()Итоги по группамПовторение — таблица лидеров11Обработка ошибок
Генерация ошибок с помощью stop()Перехват ошибок с помощью tryCatch()Предупреждения и finallyПроверка входных данныхПовторение — безопасный калькулятор3Множества и подсчёт
Уникальные значенияОперации с множествамиПроверка принадлежностиПодсчёт с помощью table()Повторение — гости мероприятия6Функции как значения
Анонимные функцииПередача функцийВозврат функцийЗамыкания с состояниемПовторение — правила скидок9Таблицы данных
Создание таблиц данныхСтолбцы и строкиФильтрация строкДобавление и сортировкаПовторение — отчёт о продажах12Проект — Трекер расходов
Запись расходовОбщие расходыПотренируйтесь самостоятельно: Онлайн-компилятор R