Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for a user input for 5 seconds and use a default value otherwise

Tags:

r

user-input

wait

I would like to give the user an opportunity to enter an input, and use a default value if they do not enter anything after 5 seconds.

Here's for the input part:

input <- readline(prompt="Do something? (y/n): ")

Is there a way to do it in R?

like image 841
Julien Massardier Avatar asked Jan 09 '19 14:01

Julien Massardier


People also ask

How to make python wait for user input?

We can use input() function to achieve this. In this case, the program will wait indefinitely for the user input. Once the user provides the input data and presses the enter key, the program will start executing the next statements. sec = input('Let us wait for user input.

How do I set the default input in python?

Approach 1 : Default value in python input() function using 'or' keyeword. In the above code, the input() function inside the int(), simply means the user-provided input is typecasted to integer data type. which means if the user doesn't provide any numerical input data and directly press Enter.


2 Answers

Here is how I accomplish a window prompt allowing the user to select the number of threads to start in a cluster. It uses a default value and then it will proceed after the OK button is pressed or 5 seconds pass.

library(tcltk2)

clusterCount = 1

tklist <- list()
tklist <- within(tklist, {
  # define processor input window
  win1 <- tktoplevel()
  rb1 <- tk2radiobutton(win1)
  rb2 <- tk2radiobutton(win1)
  rb3 <- tk2radiobutton(win1)
  rb4 <- tk2radiobutton(win1)
  rbCluster <- tclVar(clusterCount)
  tkconfigure(rb1, text = "one",  variable = rbCluster, value = 1L)
  tkconfigure(rb2, text = "two",  variable = rbCluster, value = 2L)
  tkconfigure(rb3, text = "three", variable = rbCluster, value = 3L)
  tkconfigure(rb4, text = "four", variable = rbCluster, value = 4L)
  onOK <- function() {
    clusterCount <<- as.integer(tclvalue(rbCluster))
    tkdestroy(win1)
  }
  butOK <- tk2button(win1, text = "OK", width = -8, command = onOK)

  # geometry manager
  tkgrid(tk2label(win1, text = "how many cores?"), padx = 10, pady = c(15, 5))
  tkgrid(rb1, padx = 10, pady = c(0, 5))
  tkgrid(rb2, padx = 10, pady = c(0, 15))
  tkgrid(rb3, padx = 10, pady = c(0, 15))
  tkgrid(rb4, padx = 10, pady = c(0, 15))
  tkgrid(butOK, padx = 10, pady = c(5, 15))
  tclAfter(5000, function() tkdestroy(win1)) # delay for prompt and then close window to proceed
  tkfocus(win1)
  tkwait.window(win1)
})

After the window closes then clusterCount will either remain the default 1 or can be changed to 2, 3, or 4.

like image 142
manotheshark Avatar answered Nov 14 '22 17:11

manotheshark


If you have a newer version of R then you can try withTimeout function from the utils package, to wrap the readline function.

There is a difficult to use function in base R called setTimeLimit.

My buggy attempt at a solution follows This worked in RGui, but it also seemed to reliably crash R-studio

timed_readline <- function(prompt = '',default,timeout = 10)
{
    inner <- function(timeout)    # wrapped in internal function to stop error being displayed
    {
        setTimeLimit(elapsed=timeout,transient=TRUE)
        a <- readline('')
        setTimeLimit(transient=TRUE)
        return(a)
    }

    cat(prompt)
    b <- default
    try({b <- inner(timeout)},silent=TRUE) 
    return(b)
}

As such I can't recommend this code but it might inspire you to something workable

like image 42
Aaron Hayman Avatar answered Nov 14 '22 17:11

Aaron Hayman