R: I fail to pause my code - r

I am trying to pause my code for a little while, time for me to observe the plots.
I tried:
print('A')
something = readline("Press Enter")
print('B')
print('C')
, then there is no pause, the line print('B') is fed to readline and get stored into something and therefore only A and C got printed on the screen. Note that if I add an empty line between Something = readline("Press Enter") and print("B"), then print("B") get printed on the screen but still the console doesn't allow the user to press enter before continuing.
And I tried:
print('A')
Sys.sleep(3)
print('B')
print('C')
The program waits 3 seconds before starting and then run "normally" without doing any pause between print('A') and print('B').
What do I missunderstand?
Here is my R version: R 3.1.1 GUI 1.65 Snow Leopard build (6784)

The problem with readline is that if you paste your script into an R console, or execute it from eg Rstudio, the redline function is read and then the next line of the script is read in as the console entry, which in your case sets the value of something to print('B).
An easy way to get around this is to stick your entire code in a function, then call the function to run it. So, in your case:
myscript = function(){
print('A')
something = readline(prompt = "Press Enter")
print('B')
print('C')
}
myscript()
The output of this for me (in Rstudio, with R version 3.1.1):
[1] "A"
Press Enter
[1] "B"
[1] "C"
This has always felt like a bit of a hack to me, but it's essentially what the readline documentation recommends in its example.
I've never used sleep in my code, so I can't help you there.
Edit to clarify based on comments: This will only work if myscript() is the very last line of your script, or if it is manually entered into the console after running the script to generate the function. Otherwise, you will run into the same problem as before- the next line of code will be automatically entered.

Related

Non-blocking cell execution in Jupyter

In Jupyter with an ipython kernel, is there a canonical way to execute cells in a non-blocking fashion?
Ideally I'd like to be able to run a cell
%%background
time.sleep(10)
print("hello")
such that I can start editing and running the next cells and in 10 seconds see "hello" appear in the output of the original cell.
I have tried two approaches, but haven't been happy with either.
(1) Create a thread by hand:
def foo():
time.sleep(10)
print("hello")
threading.Thread(target=foo).start()
The problem with this is that "hello" is printed in whatever cell is active in 10 seconds, not necessarily in the cell where the thread was started.
(2) Use a ipywidget.Output widget.
def foo(out):
time.sleep(10)
out.append_stdout("hello")
out = ipywidgets.Output()
display(out)
threading.Thread(target=foo,args=(out,)).start()
This works, but there are problems when I want to update the output (think of monitoring something like memory consumption):
def foo(out):
while True:
time.sleep(1)
out.clear_output()
out.append_stdout(str(datetime.datetime.now()))
out = ipywidgets.Output()
display(out)
threading.Thread(target=foo,args=(out,)).start()
The output now constantly switches between 0 and 1 lines in size, which results in flickering of the entire notebook.
This should be solvable wait=True in the call to clear_output. Alas, for me it results in the output never showing anything.
I could have asked about that issue, which seems to be a bug, specifically, but I wondered whether there is maybe another solution that doesn't require me doing all of this by hand.
I've experienced some issues like this with plotting to an output, it looks like you have followed the examples in the ipywidgets documentation on async output widgets.
The other approach I have found sometimes helpful (particularly if you know the size of the desired output) is to fix the height of your output widget when you create it.
out = ipywidgets.Output(layout=ipywidgets.Layout(height='25px'))

How can code execution be paused until a key is pressed?

I'm trying to get R to pause code execution, for the user to review some prior console output, to verify that file links have been correctly matched (using RegEx to match file names to their respective objects).
From some other answers, I've come up with:
readline(prompt="Press [enter] to continue or [esc] to exit")
As a stand alone line of code, this works as expected, but as soon as I add code below it, and send the whole block to the console, it runs right through the readline call without stopping:
readline(prompt="Press [enter] to continue or [esc] to exit")
x <- 1
y <- 2
Is there a way to get R to actually pause here?
I've also tried wrapping readline in a function, but it still doesn't work
pause <- function(){
p <- readline(prompt="Press [enter] to continue or [esc] to exit")
return(p)
}
pause()
x <- 1
y <- 2
Edit:
If I call the script via source(), readline does work properly. Is there a way to get that behavior without doing that?
By "send the whole block to the console", it sounds like you are copy-pasting your code into a running R instance.
If you do that, R will run each line in the order it receives it, as soon as it receives it. If any of the lines tries to take input, that input will come from whatever you are copy-pasting. So if you copy-paste this:
readline(prompt="Press [enter] to continue or [esc] to exit")
x <- 1
y <- 2
R will read and run the first line first. That first line will run and read the next line of input (which is a blank line here). Then R will come back and read and execute the other two lines.
You need to get your code entered into R completely before any of it runs. Try wrapping the whole thing in a function:
dostuff <- function(){
readline(prompt="Press [enter] to continue or [esc] to exit")
x <- 1
y <- 2
}
dostuff()
Using scan would always work:
message("Press [enter] to continue or [esc] to exit")
scan(quiet = TRUE, what = "")

AutoIt Scripting for an External CLI Program - eac3to.exe

I am attempting to design a front end GUI for a CLI program by the name of eac3to.exe. The problem as I see it is that this program sends all of it's output to a cmd window. This is giving me no end of trouble because I need to get a lot of this output into a GUI window. This sounds easy enough, but I am begining to wonder whether I have found one of AutoIt's limitations?
I can use the Run() function with a windows internal command such as Dir and then get the output into a variable with the AutoIt StdoutRead() function, but I just can't get the output from an external program such as eac3to.exe - it just doesn't seem to work whatever I do! Just for testing purposesI I don't even need to get the output to a a GUI window: just printing it with ConsoleWrite() is good enough as this proves that I was able to read it into a variable. So at this stage that's all I need to do - get the text (usually about 10 lines) that has been output to a cmd window by my external CLI program into a variable. Once I can do this the rest will be a lot easier. This is what I have been trying, but it never works:
Global $iPID = Run("C:\VIDEO_EDITING\eac3to\eac3to.exe","", #SW_SHOW)
Global $ScreenOutput = StdoutRead($iPID)
ConsoleWrite($ScreenOutput & #CRLF)
After running this script all I get from the consolWrite() is a blank line - not the text data that was output as a result of running eac3to.exe (running eac3to without any arguments just lists a screen of help text relating to all the commandline options), and that's what I am trying to get into a variable so that I can put it to use later in the program.
Before I suggest a solution let me just tell you that Autoit has one
of the best help files out there. Use it.
You are missing $STDOUT_CHILD = Provide a handle to the child's STDOUT stream.
Also, you can't just do RUN and immediately call stdoutRead. At what point did you give the app some time to do anything and actually print something back to the console?
You need to either use ProcessWaitClose and read the stream then or, you should read the stream in a loop. Simplest check would be to set a sleep between RUN and READ and see what happens.
#include <AutoItConstants.au3>
Global $iPID = Run("C:\VIDEO_EDITING\eac3to\eac3to.exe","", #SW_SHOW, $STDOUT_CHILD)
; Wait until the process has closed using the PID returned by Run.
ProcessWaitClose($iPID)
; Read the Stdout stream of the PID returned by Run. This can also be done in a while loop. Look at the example for StderrRead.
; If the proccess doesnt end when finished you need to put this inside of a loop.
Local $ScreenOutput = StdoutRead($iPID)
ConsoleWrite($ScreenOutput & #CRLF)

Avoid R terminal printing typed characters while performing a task

I'm using vanilla R on Linux, and when R is computing something and I press keyboard buttons, they get printed to the terminal.
For example, if I type "foo" while R is sleeping, the following happens:
Sys.sleep(1) #Typing "foo" now before the sleep ends...
foo>foo #"foo" is both registered and shown before the sleep ends
This of course may be wanted in some cases, but there are cases in which I'd like the terminal to be as clean as possible. In this case both the following options would be good:
Ignore any keypress that is registered before the completion of the previous command;
Do not ignore keypresses, but simply do not show them before the completion of the previous command.
To clarify, this is what should happen in those two cases if you write "foo" while R is sleeping:
1:
Sys.sleep(1) #Typing "foo" now before the sleep ends...
> #Nothing is registered
2:
Sys.sleep(1) #Typing "foo" now before the sleep ends...
>foo #"foo" is registered but not shown before the sleep ends
Is there any way I can accomplish one of the two?

Programmatically close the window created by `View(x)`

I'm viewing a dataframe in R using View:
my_df <- data.frame(a=1:10, b=letters[1:10])
View(my_df)
I'd like to now close the resulting window programmatically (rather than clicking the X button).
How may I do this? graphics.off doesn't work as it isn't a graphics device. Looking at the View code, internal function dataviewer is used to display the window but I'm not sure what it uses in the background (tcltk?) so am not sure how to close the window.
Re some comments as to why I want this.
I'm basically doing a user-checking step in a script whereby the user is asked if a snippet of a dataframe and a corresponding image go together. It goes something like this:
for (i in 1:heaps) {
1. View(a snippet of a big dataframe)
2. show an image
3. readline('Is this OK? [Y/N]: ') (store the i for which it's not OK)
4. close the image window (graphics.off()), close the View(..) window.
}
I basically wanted to reduce the user interaction down staring at the image & dataframe snippet and typing Y or N, so they don't have to manually close th dataframe window for each i in the loop.
(I'm part-way through this validation myself and am dealing with 200 View(snippet) windows that I haven't bothered to close D:. Also, have noticed that the opening of the windows steals keyboard focus away from the prompt so me typing Y/N is not as fast as I'd like. But I only have to do this once, so it'll do for now. I am curious as to the answer to the question though, for next time).
One way to accomplish what you're after is to make use of the system function. You could, for example, determine the Window ID/Name and then issue a close command like so:
system('(sleep 10; wmctrl -c "Data: my_df") &')
The above command will wait 10 seconds, and then issue a command to the window manager to close any window with the name "Data: my_df". These 2 commands are wrapped in parens. This is known as a Compound Command in bash. The entire Compound Command is backgrounded, '&'.
I tested the following and it worked:
# sample1.R
my_df <- data.frame(a=1:10, b=letters[1:10])
system('(sleep 10; wmctrl -c "Data: my_df") &')
View(my_df)
Another way to accomplish this is like so:
# sample2.R
my_df <- data.frame(a=1:10, b=letters[1:10])
View(my_df)
system('read -p "Press [Enter] key to start backup..."')
my_df2 <- data.frame(a=1:10, b=letters[1:10])
View(my_df2)
system('read -p "Press [Enter] key to start backup..."')
I'm running these like this:
R CMD BATCH sample2.R
NOTE: The prompt from the read -p command isn't showing up in my terminal but you could just print a duplicate prompt message in R.
If you want to close all open "View" windows, building on the answer of slm :
CloseViews <- function(){
cmd <- paste0('wmctrl -c "Data:" -v')
ok <- TRUE
while(ok){
out <- suppressWarnings(system(cmd,intern=TRUE,ignore.stderr=TRUE))
Sys.sleep(0.2)
ok <- is.null(attr(out,"status"))
print(ok)
}
}
Then CloseViews() does the trick, which I found particularly helpful when working interactively.

Resources