How to key in "Yes" or "No" in Jupyter notebook

2.7k views Asked by At

I already referred this post and this post. But it doesn't solve my problem. Please don't mark it as duplicate

I am trying to run the below piece of code in Jupyter Notebook with R kernel.

model_predictors <- buildModel(flag, fv_full_data, outcomeName, folder)

I get an error message like below

Model about to be built   # this is log message and not error

1 package is needed for this model and is not installed. (randomForest). Would you like to try to install it now?    # here I see that it asks for a question but without my input it selects `No`
Error: Required package is missing
Traceback:

1. buildModel(flag, fv_full_data, outcomeName, folder)
2. train(x = trainDF[, predictorsNames], y = factor(trainLabels), 
 .     method = "rf", metric = "Fscore", trControl = objControl, 
 .     tuneGrid = rf_grid, preProcess = c("center", "scale"))
3. train.default(x = trainDF[, predictorsNames], y = factor(trainLabels), 
 .     method = "rf", metric = "Fscore", trControl = objControl, 
 .     tuneGrid = rf_grid, preProcess = c("center", "scale"))
4. checkInstall(models$library)
5. stop("Required package is missing", call. = FALSE)

How can I avoid this error and prevent jupyter selecting No as default for dynamic prompts?

2

There are 2 answers

0
Paul On BEST ANSWER

In your example, you actually never reach the part of code that handles input. These inputs only occur for interactive sessions - which Jupyter is not. You can check with

interactive()
#> FALSE

menu(c("yes", "no"))
#> Error in menu(c("yes", "no")): menu() cannot be used non-interactively
#> Traceback:
#> 
#> 1. menu(c("yes", "no"))
#> 2. stop("menu() cannot be used non-interactively")

caret::checkInstall prints out the message "Would you like to try to install x now?", but it will only accept input for interactive sessions.

Here is the code for caret::checkInstall with my comments.

function (pkg) 
{
    good <- rep(TRUE, length(pkg))
    for (i in seq(along = pkg)) {
        tested <- try(find.package(pkg[i]), silent = TRUE)
        if (inherits(tested, "try-error")) 
            good[i] <- FALSE
    }
    if (any(!good)) {
        pkList <- paste(pkg[!good], collapse = ", ")
        msg <- paste(sum(!good), ifelse(sum(!good) > 1, " packages are", 
            " package is"), " needed for this model and", 
            ifelse(sum(!good) > 1, " are", " is"), 
            " not installed. (", pkList, "). Would you like to try to install", 
            ifelse(sum(!good) > 1, " them", " it"), 
            " now?", sep = "")
        cat(msg) # Print the message
        if (interactive()) { # In Jupyter, `interactive()` is `FALSE`.
            bioc <- c("affy", "logicFS", "gpls", 
                "vbmp")
            installChoice <- menu(c("yes", "no")) # This is where it gets input
            if (installChoice == 1) {
                hasBioc <- any(pkg[!good] %in% bioc)
                if (!hasBioc) {
                  install.packages(pkg[!good])
                }
                else {
                  inst <- pkg[!good]
                  instC <- inst[!(inst %in% bioc)]
                  instB <- inst[inst %in% bioc]
                  if (length(instC) > 0) 
                    install.packages(instC)
                  biocLite <- NULL
                  source("http://bioconductor.org/biocLite.R")
                  biocLite(instB)
                }
            }
            else stop("Required package is missing", call. = FALSE)
        }
        else stop("Required package is missing", call. = FALSE) # Because `interactive()` is `FALSE`, this `stop` is called
    }
}

For your situation, install.packages("randomForest") is the best option.

If you were in RStudio, you could use the rstudioapi like this

f <- function() {
  rstudioapi::sendToConsole("1")
  menu(c("yes", "no"))
}
f()
#> 1: yes
#> 2: no
#> 
#> Selection: 1
#> [1] 1
6
questionto42 On

Mind that in modern Jupyter Notebooks, you better take Magic commands (starting with % instead of ! in front of a command), see the comments.


I did not test with the R kernel, but this might still help someone.

Example: Python package manager conda

You can add -y to the install command so that a "yes" is the default for any yes/no prompt.

This does not work:

!conda install matplotlib

Output:

Channels:
 - defaults
Platform: linux-64
Collecting package metadata (repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: /opt/conda/envs/anaconda-panel-2023.05-py310

  added / updated specs:
    - matplotlib


The following packages will be UPDATED:

  certifi                         2023.7.22-py311h06a4308_0 --> 2023.11.17-py311h06a4308_0 
  openssl                                 3.0.10-h7f8727e_2 --> 3.0.12-h7f8727e_0 


Proceed ([y]/n)? 

Which I cannot enter since there is no interactive user prompt in Jupyter Notebook.

On the other hand,

!conda install matplotlib -y

does not ask for yes/no anymore. You tell that you have already tried this and that it does not work for the R Kernel, but at least for python installers, it should be tried.

Example: apt-get install

The question lists the link that shows:

apt-get -y install [packagename]`

But if you check Automatically answer 'Yes' when using apt-get install on Super User and then scroll through other answers there, you will find other tricks like:

!DEBIAN_FRONTEND=noninteractive
!apt-get --yes --force-yes install $something

PS: Since these tricks did not work for the R Kernel, this answer does not help answering the question as a whole, but at least, it may be an answer to its title. It might be a little step beyond the already given link.