数字练习的部分学分(例如猜测任务)?

Partial credit for numeric exercises (e.g. for guessing tasks)?

我正在教学生从典型的绘图类型(例如 Pearson 的 r 来自散点图和平行坐标图,Kendall 的 τ 来自冲积地块,Cramer 的 V 来自马赛克图,...)。使用 {exams} 包动态生成此类任务非常有效。
然而,当我在 moodle 中使用 r-exams 生成的问题,并且 moodle 允许对 数字问题类型 给予部分学分时,我想知道是否有办法通过{exams}.
将答案转换为部分学分的可能函数可以是

我认为在 Moodle 中不可能使用连续函数分配部分学分。但是对于 Moodle 完形填空问题中的 NUMERICAL 个答案,您可以设置部分学分的离散步骤,请参阅随附的 Moodle docs

R/exams 目前没有为具有 num 元素的 cloze 问题生成此类部分学分的便利功能。但是,可以将 verbatim 元素放入完形填空,其中 exsolution 包含 Moodle NUMERICAL 语法。有关有效示例,请参阅 confint3 练习模板。

为了做与您描述的类似的事情,我编写了一个小的便利函数 num_to_moodle(),它通过离散阶跃函数逼近连续函数。语法为 num_to_moodle(x, tol = 0, breaks = 1, range = NULL) 其中:

  • x是正确解,
  • tol是100%点的公差,
  • breaks 是达到 0% 分数的额外步数,超出最大容差 tol * breaks
  • range 是考虑部分学分的可选范围。

作为说明,我包括一个显示散点图的简短练习,学生必须“猜测”相关系数 r(在 -0.9、-0.6、...、0.9 中采样)。设数值解为:num_to_moodle(r, tol = 0.06, breaks = 5, range = c(-1, 1))。这意味着 r plus/minus 0.06 被 100% 的点接受,下一个 0.06(双向)80%,下一个 0.06 60%,等等。超出 plus/minus 的一切0.3 的收益率为 0%。超出 -1 或 1 的部分信用解决方案被排除在外。 (准确地说:仅排除该区间之外的中点。由于公差,略微超出该区间的解可能仍会产生点数。)

num_to_moodle()函数的源代码是:

num_to_moodle <- function(x, tol = 0, breaks = 1, range = NULL, digits = 5) {
  ## round correct solution and tolerance
  breaks <- round(breaks)
  x <- round(x, digits = digits)
  tol <- round(tol, digits = digits)

  ## only correct solution without tolerance
  if(breaks <= 0L || (breaks == 1L && tol <= 0)) return(paste0(":NUMERICAL:=", x))

  ## only correct solution with tolerance
  if(breaks == 1L) return(paste0(":NUMERICAL:=", x, ":", tol))

  ## multiple partial solutions with tolerances
  if(!(breaks %in% c(2:6, 10))) stop("'breaks' must be 0, 1, ..., 6, or 10")
  perc <- exams:::moodlePercent((breaks:1L)/breaks)
  y <- seq(x + 1.5 * tol, by = tol, length.out = breaks - 1L)

  ## set up Moodle string: :NUMERICAL:=solution1~solution2~solution3 etc.
  ## where each solution has: %_percent_%_solution_:_tolerance_#_comment_
  perc <- c("", paste0("%", rep.int(perc[-1], 2), "%"))
  x <- round(c(x, y, x + (x - y)), digits = digits)
  tol <- c(tol, rep.int(tol/2, 2 * (breaks - 1L)))
  if(!is.null(range)) {
    if(length(range) != 2L) stop("'range' must have length 2")
    ok <- (x >= range[1L]) & (x <= range[2L])
    if(!ok[1L]) stop("'x' is not within 'range'")
  } else {
    ok <- rep.int(TRUE, 2 * breaks - 1L)
  }
  num <- paste0(":NUMERICAL:=", paste0(
    perc[ok],        ## percents
    x[ok],           ## solutions
    ":", tol[ok],    ## tolerances
    "",              ## comments (none for now)
    collapse = "~")) ## collapse
  return(num)
}

上面的屏幕截图是根据以下内容生成的:

set.seed(0)
exams2moodle("correlation.Rmd")

其中 correlation.Rmd 练习包含以下文本:

```{r, include = FALSE}
r <- sample(seq(-0.9, 0.9, by = 0.3), 1)
x <- rnorm(200)
y <- r * x + rnorm(200, sd = sqrt(1 - r^2))
r <- cor(x, y)
```

Question
========

Consider the following scatterplot:
\
```{r scatterplot, echo = FALSE, results = "hide", fig.height = 5, fig.width = 5, fig.path = "", fig.cap = ""}
plot(x, y)
```

Answerlist
----------
* Estimate the correlation of x and y:


Meta-information
================
exname: Correlation
extype: cloze
exclozetype: verbatim
exsolution: `r num_to_moodle(r, tol = 0.06, breaks = 5, range = c(-1, 1))`