Kiểm tra đầu vào
Thuộc phần Logic và luồng điều khiển trong hành trình R của Coddy. Bài học 55 trên 64.
Đầu vào từ người dùng hoặc tệp là văn bản và có thể chứa bất cứ thứ gì. Hãy kiểm tra trước khi sử dụng: suppressWarnings(as.numeric(s)) trả về NA với văn bản không phải là số, còn is.na() kiểm tra điều đó:
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"))Đầu ra:
[1] "age 36"
[1] "not a number"
[1] "out of range"Một hàm kiểm tra có thể thu thập mọi vấn đề thay vì dừng lại ở vấn đề đầu tiên, nhờ đó đưa ra phản hồi hữu ích hơn. Ở đây, hàm trả về một vector chứa các thông báo, vector này rỗng khi dữ liệu đầu vào hợp lệ:
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")))Đầu ra:
[1] "too short" "needs a digit"
[1] 0Chọn cách xử lý dựa trên nơi gọi hàm: trả về một thông báo khi nơi gọi dự kiến có đầu vào không hợp lệ và hiển thị thông báo đó cho người dùng; phát sinh lỗi bằng stop() khi đầu vào không hợp lệ cho thấy có lỗi trong chương trình và không nên bị bỏ qua.
# Bên gọi dự kiến đầu vào không hợp lệ và hiển thị thông báo
read_age("abc") # "not a number"
# Đầu vào không hợp lệ là lỗi trong chương trình
if (!is.numeric(x)) stop("x must be numeric")Việc xác thực bằng tryCatch() quanh bước phân tích giúp phần code chính không cần các bước kiểm tra: mỗi bản ghi hoặc được chuyển đổi, hoặc được báo lỗi:
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")
}Đầu ra:
tea,2 : ok 2
jam : expected 2 fields
oil,x : quantity is not a whole number Thử thách
DễHoàn thiện check_signup(name, age, email). Thu thập mọi vấn đề theo thứ tự này: name is empty (sau khi xóa khoảng trắng ở hai đầu), age must be a number, age must be 13 or older (chỉ khi tuổi là một số) và email needs @. Trả về ok khi không có vấn đề nào, nếu không thì nối các vấn đề bằng ; .
Code được cung cấp đọc tên, tuổi và email (mỗi giá trị trên một dòng) rồi in ra giá trị trả về.
Tự làm thử
check_signup <- function(name, age, email) {
# Viết code của bạn ở đây
"ok"
}
# Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
cat(check_signup(input[1], input[2], input[3]), sep = "\n")
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Chuỗi chuyên sâu
Chuỗi con với substr()Định dạng với sprintf()Tách và nối chuỗiTìm kiếm trong chuỗiThay thế văn bảnÔn tập: Tạo tên người dùng10Luồng điều khiển nâng cao
Hàm switch()ifelse() dạng vector hóarepeat và breakHàm đệ quyÔn tập: phân loại điểm2Tra cứu khóa-giá trị
Tra cứu vector theo tênKiểm tra khóaThêm và xóa khóaLặp qua các tênÔn tập: Bàn giao dịch cổ phiếu11Xử lý lỗi
Phát sinh lỗi với stop()Bắt lỗi với tryCatch()Cảnh báo và finallyKiểm tra đầu vàoÔn tập: Máy tính an toànTự luyện tập: Trình biên dịch R online