From 160ba87308310a38f66f3fe7c4c40fc756c995a7 Mon Sep 17 00:00:00 2001 From: USATVIKA Date: Sun, 30 Nov 2025 15:50:39 -0600 Subject: [PATCH] clean up --- .../introduction-to-python/tutorial.Rmd | 101 +++++++----------- 1 file changed, 39 insertions(+), 62 deletions(-) diff --git a/inst/tutorials/introduction-to-python/tutorial.Rmd b/inst/tutorials/introduction-to-python/tutorial.Rmd index f7e6c4b..065c932 100644 --- a/inst/tutorials/introduction-to-python/tutorial.Rmd +++ b/inst/tutorials/introduction-to-python/tutorial.Rmd @@ -17,28 +17,19 @@ description: Tutorial for introducing students to the Python language. +```{r setup, include=FALSE} +# ------------------------------------------------------------------- +# Global setup: R packages + Python virtualenv for the tutorial +# ------------------------------------------------------------------- - -```{r early-env, include=FALSE} -# Don't let reticulate autoconfigure arbitrary Pythons +# Don't let reticulate auto-pick some random Python Sys.setenv(RETICULATE_AUTOCONFIGURE = "FALSE") -is_windows <- identical(.Platform$OS.type, "windows") - -# Point to venv Python only if it exists; use OS-appropriate path -py_guess <- if (is_windows) ".venv/Scripts/python.exe" else ".venv/bin/python" -if (file.exists(py_guess)) { - Sys.setenv(RETICULATE_PYTHON = normalizePath(py_guess, winslash = "/", mustWork = FALSE)) -} - -``` - -```{r setup, include=FALSE} # ---- Safe CRAN mirror + interactive-only installs ---- if (is.null(getOption("repos")["CRAN"]) || !nzchar(getOption("repos")["CRAN"])) { options(repos = c(CRAN = "https://cloud.r-project.org")) } -needed <- c("learnr","tutorial.helpers","knitr","reticulate") +needed <- c("learnr", "tutorial.helpers", "knitr", "reticulate") to_install <- setdiff(needed, rownames(installed.packages())) if (interactive() && length(to_install)) { install.packages(to_install, quiet = TRUE) @@ -57,59 +48,42 @@ learnr::tutorial_options( # ---- Environment flags ---- is_windows <- identical(.Platform$OS.type, "windows") -in_ci <- !interactive() || identical(tolower(Sys.getenv("CI")), "true") - -# ---- Python/reticulate behavior ---- -if (in_ci) { - # Don’t execute Python in CI (render code only) - knitr::knit_engines$set( - python = function(options) { - knitr::engine_output(options, code = options$code, - out = "\n\n") - } - ) -} else { - # Use local venv if present; do not install anything here - venv <- ".venv" - py_bin <- if (is_windows) file.path(venv, "Scripts", "python.exe") else file.path(venv, "bin", "python") - if (file.exists(py_bin)) { - Sys.setenv(RETICULATE_PYTHON = normalizePath(py_bin, winslash = "/", mustWork = FALSE)) - reticulate::use_virtualenv(venv, required = FALSE) - } - # Enable Python engine (reticulate) - knitr::knit_engines$set(python = reticulate::eng_python) -} - - -``` - -```{r bootstrap-python-venv, include=FALSE} -# --- Robust, cross-platform venv bootstrap (works locally, safe on CI) --- - -is_windows <- identical(.Platform$OS.type, "windows") -venv <- ".venv" -py_bin <- if (is_windows) file.path(venv, "Scripts", "python.exe") else file.path(venv, "bin", "python") - -# Detect CI / R CMD check: don't try to build a venv or run Python then. in_ci <- identical(tolower(Sys.getenv("CI")), "true") || identical(tolower(Sys.getenv("R_CMD_CHECK")), "true") || !interactive() +venv <- ".venv" +py_bin <- if (is_windows) file.path(venv, "Scripts", "python.exe") else file.path(venv, "bin", "python") + if (in_ci) { - # Render-only: don't execute Python, don't create venv + # ----------------------------------------------------------------- + # CI / R CMD check: render-only, no Python execution or venv setup + # ----------------------------------------------------------------- knitr::knit_engines$set( python = function(options) { - knitr::engine_output(options, code = options$code, - out = "\n\n") + knitr::engine_output( + options, + code = options$code, + out = "\n\n" + ) } ) + } else { - # 1) Pick a system Python + # ----------------------------------------------------------------- + # Local use: create/activate .venv in this tutorial directory + # ----------------------------------------------------------------- + + # 1) Find a system Python python_exe <- Sys.which(if (is_windows) "python" else "python3") - if (!nzchar(python_exe)) python_exe <- reticulate::py_discover_config()$python - if (!nzchar(python_exe)) stop("No usable system Python found to create .venv.") + if (!nzchar(python_exe)) { + python_exe <- reticulate::py_discover_config()$python + } + if (!nzchar(python_exe)) { + stop("No usable system Python found to create .venv.") + } - # 2) Create .venv if missing + # 2) Create .venv if missing (do NOT delete if it already exists) if (!dir.exists(venv)) { message("Creating .venv with: ", python_exe) reticulate::virtualenv_create(envname = venv, python = python_exe) @@ -119,20 +93,23 @@ if (in_ci) { Sys.setenv(RETICULATE_PYTHON = normalizePath(py_bin, winslash = "/", mustWork = FALSE)) reticulate::use_virtualenv(venv, required = TRUE) - # 4) Upgrade pip tooling (use python -m pip to avoid OS-specific pip paths) - system2(py_bin, c("-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"), - stdout = TRUE, stderr = TRUE) + # 4) Upgrade pip tooling via `python -m pip` (portable, no pip.exe assumption) + system2( + py_bin, + c("-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel"), + stdout = TRUE, + stderr = TRUE + ) - # 5) Install required packages (again via python -m pip) + # 5) Install required Python packages into this .venv req <- c("polars", "pandas", "numpy", "plotnine", "matplotlib", "seaborn") system2(py_bin, c("-m", "pip", "install", req), stdout = TRUE, stderr = TRUE) - # 6) Ensure knitr uses reticulate's Python engine + # 6) Tell knitr to use reticulate's Python engine knitr::knit_engines$set(python = reticulate::eng_python) } ``` - ```{r copy-code-chunk, child = system.file("child_documents/copy_button.Rmd", package = "tutorial.helpers")} ```