如何使用函数```num_to_schoice()```?

how to use the function ```num_to_schoice()```?

我想构建一个简单的概率练习,使得解只是一个介于 0 和 1 之间的小数(不同于 0 和 1)。我想使用函数 num_to_schoice,但是如果我写:

num_to_schoice(0.3,digits=1,range=c(0.1,0.9))

我收到错误消息:

NULL Warning message: In num_to_schoice(0.3, digits = 1, range = c(0.1, 0.9)) : specified 'range' is too small for 'delta'

有人可以解释一下函数 num_to_schoice 应该如何正确使用吗?

因为您的范围是 (0, 1),所以您必须指定比默认值 (1) 更小的 delta。该函数计算出 5 个错误答案,因此每个答案都必须在您给出的范围内,并且与其他答案的距离足够远 delta。您还应该使用 "delta" 方法,因为包作者给出了以下建议:

Two methods can be used to generate the wrong solutions: Either simply runif or otherwise a full equi-distant grid for the range with step size delta is set up from which a discrete uniform sample is drawn. The former is preferred if the range is large enough while the latter performs better if the range is small (as compared to delta).

所以您可以尝试以下方法:

num_to_schoice(0.3, digits=1, range=c(0.1, 0.9), delta=0.05, method="delta")
#$solutions
#[1] FALSE FALSE FALSE  TRUE FALSE

#$questions
#[1] "[=10=].6$" "[=10=].5$" "[=10=].3$" "[=10=].4$" "[=10=].8$"

请注意,此函数包含随机性,因此您可能需要尝试几次才能出现有效的解决方案。继续忽略错误。


编辑: 我确实尝试过几次,时不时地收到有关指定范围太小的警告,并返回 NULL 结果。其他时候该功能什么也没做,我不得不中止。帮助页面也有这个花絮:

Exercise templates using num_to_schoice should be thoroughly tested in order to avoid problems with too small ranges or almost identical correct and wrong answers! This can potentially cause problems, infinite loops, etc.

检查num_to_schoice函数,发现在接近尾部的地方有一个while循环,可能会卡在前面提到的"infinite loop"中。长话短说,看起来您需要将数字至少增加到 2,否则这个循环可能永远不会结束。我希望答案中有 2 位数是可以的。

num_to_schoice(0.3, digits=2, range=c(0.1, 0.9), delta=0.01, method="delta")

$solutions
[1] FALSE FALSE FALSE  TRUE FALSE

$questions
[1] "[=11=].23$" "[=11=].42$" "[=11=].22$" "[=11=].30$" "[=11=].54$"

我试了 10,000 次,它总是返回非空结果。

res <- NULL
for(i in 1:10000){
  res[[i]] <- num_to_schoice(0.3, digits=2, range=c(0.1, 0.9), delta=0.01, method="delta")
}
sum(sapply(res, function(x) any(is.null(x))))
# [1] 0

希望现在有用。

让我对@Edward (+1) 的现有答案补充几点:

如果您从序列 0.1, 0.2, ..., 0.9 中生成一个解决方案,并希望将剩余八个数字中的四个作为干扰项,我建议不要使用 num_to_schoice()。只有在 0.10、0.11、0.12、...、0.9 中移动到正确的解决方案时,我才会使用 num_to_schoice().

一位数字没有num_to_schoice()

您可以设置一个包含序列中所有九个数字的答案列表,将正确的答案排在第一位,然后使用 exshuffle 元信息标签进行实际抽样。

例如,在数据生成中你需要这样的东西:

sol <- 0.3
ans <- c(sol, setdiff(1:9/10, sol))
ans <- paste0("$", ans, "$")

然后您可以在问题中包含

answerlist(ans, markup = "markdown")
## Answerlist
## ----------
## * [=11=].3$
## * [=11=].1$
## * [=11=].2$
## * [=11=].4$
## * [=11=].5$
## * [=11=].6$
## * [=11=].7$
## * [=11=].8$
## * [=11=].9$

最后,元信息需要:

exsolution: 100000000
exshuffle: 5

然后这将使用正确的解决方案和八个错误答案中的四个 - 所有这些都是随机排列的。 (请注意,上面使用 .Rmd 语法,对于 .Rnw 这需要相应地进行调整。)

两位数用num_to_schoice()

对于一位使用 num_to_schoice() 的场景,它试图做太多的事情,但对于多于一位的情况,它可能很有用。具体来说,num_to_schoice() 确保 正确解的等级 是非信息性的,即,正确的解可以是最小的、第二小的、...、最大的数在显示的序列中以相等的概率出现。具体来说,如果正确解在可能范围内的分布不均匀,这可能很重要。这就是以下代码有时会失败的原因:

num_to_schoice(0.3, digits = 1, delta = 0.1, range = c(0.1, 0.9))

在内部,这首先决定四个错误答案中有多少应该在正确答案 0.3 的左边。显然,左边最多有两个错误答案的空间,如果超过,可能会导致警告和 NULL 结果。移动到两位数可以解决这个问题,例如:

num_to_schoice(0.31, range = c(0.01, 0.99),
  digits = 2, delta = 0.03, method = "delta")

备注:

  • 就个人而言,只有当正确的解决方案可能也有两位数时,我才会这样做。否则学生可能会选择这种模式。
  • 您需要确保在正确答案的左侧和右侧至少有 4 * delta 以便有足够的空间容纳错误答案。
  • 当然可以使用 delta = 0.01,但如果您想要更大的增量,那么 delta = 0.03delta = 0.07 通常也是有用的选择。这是因为对于大多数学生来说,从具有这种增量的等距网格中采样通常不会引起注意。相比之下,通常可以快速拾取 0.05、0.1、0.02 等增量。