3 # The following R program was designed for use in cold calling in a
4 # class room environment that tries to balance true randomness with
5 # the desire to spread questions out.
7 # The software was written by Benjamin Mako Hill <mako@atdot.cc> and
8 # is released into the public domain.
10 # replace this line with a list of the names from which we want to sample
11 member.names <- c("Alonso", "Alejandro", "Andres", "Becky",
12 "Deborah", "Lauren", "Mako", "Nikhit", "North",
15 # set the default weight: after being selected the likelihood of the
16 # selected value being chosen will be reduced to 1 over this value
19 # create a variable which we'll use to keep track of who has been selected
20 reset.weights <- function () {
21 w <- rep(1, length(member.names))
22 names(w) <- member.names
23 assign("w", w, envir=.GlobalEnv)
26 # only run this if you want to create new we
27 if (!exists("w")) reset.weights()
29 get.ping.pong.ball <- function () {
30 # create the "jar" according to the weights
31 weighted.names <- c(sapply(member.names,
32 function (x) {rep(x, w[x])}), recursive=TRUE)
33 # select something out of it
34 selected <- sample(weighted.names, 1)
36 # adjust the weights for the next run based on what was selected
37 w[!names(w) == selected] <- w[!names(w) == selected] * pp.weight
39 # if we can reduce the weights by a lowest common denom, do it
40 if (all((w %% pp.weight) == 0)) w <- w / pp.weight
42 # save the variable in the global namespace so we can return to it next time
43 assign("w", w, envir=.GlobalEnv)
45 # clean up the output and return the value
46 names(selected) <- NULL
50 # run this function to get a person selected
53 # run the following function to reset the weights