Menu
Coddy logo textTech

Doğrulayıcılar ve Yardımcılar

Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 5 / 57.

Yapıcı türleri denetler; bir doğrulayıcı ise değerleri denetler. Kural gereği validate_money() bir nesne alır, ihlal ettiği her kural için stop() işlevini açık bir mesajla çağırır ve her şey yolundaysa nesneyi döndürür. call. = FALSE, işlev çağrısının mesaja eklenmemesini sağlar:

new_money <- function(amount = double(), currency = character()) {
  stopifnot(is.double(amount), is.character(currency))
  structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
  if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
  if (nchar(x$currency) != 3) stop("currency must have 3 letters", call. = FALSE)
  x
}
m <- validate_money(new_money(-5, "EUR"))

Çıktı:

Error: amount must not be negative
Execution halted

yardımcı, diğer kodun çağırdığı işlevdir. Adını sınıftan alır, girdisini doğru türlere dönüştürür, varsayılan değerleri doldurur ve sonucu yapıcı ile doğrulayıcıdan geçirir:

new_money <- function(amount = double(), currency = character()) {
  stopifnot(is.double(amount), is.character(currency))
  structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
  if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
  x
}
money <- function(amount, currency = "EUR") {
  validate_money(new_money(as.double(amount), toupper(currency)))
}
m <- money("12", "usd")
cat(m$amount, m$currency)

Çıktı:

12 USD

Kullanıcı girdisini okuyan kod, doğrulayıcının hatalarını tryCatch() ile yakalar ve conditionMessage(e) değerini, yani stop() işlevine aktarılan metni gösterir:

validate_age <- function(x) {
  if (x$years < 0) stop("age must not be negative", call. = FALSE)
  if (x$years > 150) stop("age is too large", call. = FALSE)
  x
}
age <- function(years) validate_age(structure(list(years = as.double(years)), class = "age"))
for (input in c("30", "-2", "200")) {
  result <- tryCatch(paste("ok", age(input)$years), error = function(e) conditionMessage(e))
  cat(result, "\n")
}

Çıktı:

ok 30 
age must not be negative 
age is too large 

Üç fonksiyonun her birinin tek bir görevi vardır. new_money() katıdır ve doğru türlere zaten sahip olan kodlar için hızlıdır. validate_money() yavaş veya çok sayıda olabilen değer kurallarını içerir. money() kullanıcı dostudur ve programın geri kalanının kullandığı fonksiyondur:

new_money()       # yalnızca tipler; nesneyi structure() ile oluşturur
validate_money()  # değer kuralları; bir mesajla stop(), aksi halde x döndür
money()           # girdiyi dönüştürür, sonra validate_money(new_money(...))
challenge icon

Görev

Kolay

new_score(points, max), Score.R içinde bir score nesnesi oluşturur. Aynı dosyadaki diğer işlevleri tamamla:

  • validate_score(x), sırasıyla denetlenen points must not be negative, max must be positive veya points must not exceed max mesajlarıyla durur; aksi durumda x değerini döndürür.
  • score(points, max = 100), her iki bağı da as.double() ile dönüştürür ve validate_score(new_score(...)) sonucunu döndürür.
  • format.score(x, ...), yüzde değeri tam sayıya yuvarlanmış olarak 45/50 (90%) döndürür.

Her stop() çağrısında call. = FALSE kullan. Sağlanan kod satırları okur; 45 50 için biçimlendirilmiş puanı, aksi durumda error: ve mesajı yazdırır.

Kodun Score.R dosyasına gitmelidir. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

source("Score.R")

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  s <- tryCatch(score(p[1], p[2]), error = function(e) conditionMessage(e))
  if (is.character(s)) cat("error: ", s, "\n", sep = "") else cat(format(s), "\n", sep = "")
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Tabanlı Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online R derleyicisi