# S-290 PingPong Ball # # The following R program was designed for use in cold calling in a # class room environment that tries to balance true randomness with # the desire to spread questions out. # # The software was written by Benjamin Mako Hill and # is released into the public domain. # replace this line with a list of the names from which we want to sample member.names <- c("Alonso", "Alejandro", "Andres", "Becky", "Deborah", "Lauren", "Mako", "Nikhit", "North", "Steve") # set the default weight: after being selected the likelihood of the # selected value being chosen will be reduced to 1 over this value pp.weight <- 2 # create a variable which we'll use to keep track of who has been selected reset.weights <- function () { w <- rep(1, length(member.names)) names(w) <- member.names assign("w", w, envir=.GlobalEnv) } # only run this if you want to create new we if (!exists("w")) reset.weights() get.ping.pong.ball <- function () { # create the "jar" according to the weights weighted.names <- c(sapply(member.names, function (x) {rep(x, w[x])}), recursive=TRUE) # select something out of it selected <- sample(weighted.names, 1) # adjust the weights for the next run based on what was selected w[!names(w) == selected] <- w[!names(w) == selected] * pp.weight # if we can reduce the weights by a lowest common denom, do it if (all((w %% pp.weight) == 0)) w <- w / pp.weight # save the variable in the global namespace so we can return to it next time assign("w", w, envir=.GlobalEnv) # clean up the output and return the value names(selected) <- NULL return(selected) } # run this function to get a person selected get.ping.pong.ball() # run the following function to reset the weights reset.weights()