[1] "/Users/rundel/Library/R/arm64/4.6/library"
[2] "/Library/Frameworks/R.framework/Versions/4.6/Resources/library"
Lecture 01
We will be assessing you based on the following:
| Assignment | Type | Value | n | Assigned |
|---|---|---|---|---|
| Homeworks | Team | 35% | 5-6 | ~ Every other week |
| Midterms | Individual | 50% | 2 | ~ Week 8 and 16 |
| Quizzes | Individual | 15% | ~10-15 | ~ Weekly |
Roughly biweekly assignments
Open ended, ~5 - 15 hours of work
Randomly assigned teams of 3-4 students, teams change after each assignment
Peer evaluation after completion
Expectations and roles:
Attendance is expected - you must attend the lab you are enrolled in
Opportunity to work on course assignments with TA support
Labs will begin this week - Friday (8/28)
Each exam will have two components:
Individual take home
Similar in scope to homework
~1 week to complete
In class written exam (based on take home):
Read & evaluate code
Describe pseudo-code solutions
You must sit the in class exam in order to receive points for the take home - in the event of a documented emergency the exam will be replaced by an in person oral exam (which must be scheduled within one week of the original exam date).
Roughly once a week
Randomly in lecture or lab (start, middle, or end)
5 multiple choice questions, 5 minutes
Your lowest 3-5 quiz scores will be dropped
No excused absences for quizzes (covered by above)
We are aware that a huge volume of code is available on the web, and many tasks may have solutions posted.
Unless explicitly stated otherwise, this course’s policy is that you may make use of any online resources (e.g. Google, StackOverflow) but you must explicitly cite where you obtained any code you directly use or use as inspiration in your solution(s).
Teams should not directly share answers / code with other teams; however, you are welcome to discuss the problems in general and ask for advice.
Any recycled/copied code that is not explicitly cited will be treated as plagiarism, regardless of source.
The same applies to the use of LLMs like ChatGPT, Claude, Gemini, or GitHub Copilot - you are welcome to make use of these tools as the basis for your solutions but you must cite the tool when using it for significant code generation.
Any violation of the academic honesty standards outlined in the Duke Community Standard, the Graduate School’s Standards of Conduct, or those specific to this course:
will automatically result in a 0 for the relevant portion or the entirety of the assignment or assessment,
can result in further deductions to your overall course grade (e.g. dropping down to the next letter grade or to an F), and
can be reported to the Graduate School and the Office of Student Conduct & Community Standards for further action.
AI tools are not a replacement for understanding the material, but they can help you learn it.
Reading code and writing code are skills that take time and practice to develop - both are essential.
The nature of these tools is changing rapidly - autocomplete vs chatbots vs agentic tools
To reduce friction, the preferred method is to use the department’s RStudio server(s).
To access RStudio/Posit Workbench:
If you cannot access RStudio via the DSS servers:
Make sure you are on an authenticated Duke network (e.g. DukeBlue or VPN)
Make sure you are not using a custom DNS server
1.1.1.1 or 8.8.8.8If working locally you should make sure that your environment meets the following requirements:
latest R (4.6)
latest Python (3.14) + uv (0.12)
latest Positron (2026.08.1)
working git installation
ability to create SSH keys (for GitHub authentication)
Support policy for local installs - we will try to help you troubleshoot if we can but reserve the right to tell you to use the dept server.
We will be using a GitHub organization for this course github.com/sta523-fa26
All assignments will be distributed and collected via GitHub
All of your work and your membership (enrollment) in the organization is private
We will be distributing a survey this week to collect your GitHub account names
All course related repositories will be created for you
Not enrolled? Fill out https://bit.ly/enroll-sta523-fa26
Complete the course survey (link via email)
Create a GitHub account if you don’t have one
Make sure you can log in to the Department’s Workbench server https://rstudio.stat.duke.edu
Set up SSH key authentication with GitHub, see https://github.com/DukeStatSci/github_auth_guide
R packages are just collections of files - R code, compiled code (C, C++, Rust etc.), data, documentation, and others that live in your library path.
[1] "_build" "_cache"
[3] "abind" "airports"
[5] "and" "anytime"
[7] "ape" "archive"
[9] "arrayhelpers" "arrow"
[11] "AsioHeaders" "askpass"
[13] "assertthat" "astsa"
[15] "available" "babelwhale"
[17] "backports" "BART"
[19] "base" "base64enc"
[21] "base64url" "BayesFactor"
[23] "bayesplot" "bcf"
[25] "beeswarm" "bench"
[27] "berryFunctions" "BH"
[29] "bigD" "bit"
[31] "bit64" "bitops"
[33] "blastula" "blob"
[35] "bonsai" "bookdown"
[37] "boot" "bootstrap"
[39] "brew" "bridgesampling"
[41] "brio" "brms"
[43] "Brobdingnag" "broom"
[45] "broom.helpers" "broom.mixed"
[47] "brotli" "bs4Dash"
[49] "bsicons" "bslib"
[51] "btw" "cachem"
[53] "callr" "car"
[55] "carData" "cards"
[57] "caret" "carrier"
[59] "caTools" "cellranger"
[61] "centiserve" "checklist"
[63] "checkmate" "cherryblossom"
[65] "chromote" "chron"
[67] "circlize" "class"
[69] "classInt" "cli"
[71] "clipr" "clisymbols"
[73] "clock" "clue"
[75] "cluster" "coda"
[77] "codetools" "collections"
[79] "colorspace" "colourpicker"
[81] "commonmark" "compiler"
[83] "confintr" "conflicted"
[85] "connectapi" "connections"
[87] "contfrac" "coreNLP"
[89] "coro" "corrplot"
[91] "countdown" "countrycode"
[93] "covr" "cowplot"
[95] "cpp11" "cranlike"
[97] "crayon" "credentials"
[99] "crosstalk" "crul"
[101] "cubature" "curl"
[103] "cyclocomp" "DAAG"
[105] "data.table" "datasauRus"
[107] "datasets" "datawizard"
[109] "dbarts" "DBI"
[111] "dbplyr" "debugme"
[113] "deepgp" "deldir"
[115] "DEoptimR" "Deriv"
[117] "desc" "desirability2"
[119] "deSolve" "detectseparation"
[121] "devEMF" "devtools"
[123] "diagram" "dials"
[125] "DiceDesign" "diffmatchpatch"
[127] "diffobj" "diffviewer"
[129] "digest" "distributional"
[131] "dm" "doBy"
[133] "docopt" "doFuture"
[135] "doMC" "doParallel"
[137] "dotCall64" "dotty"
[139] "downlit" "dplyr"
[141] "DT" "dtplyr"
[143] "dtt" "duckdb"
[145] "duckknit" "duckplyr"
[147] "dygraphs" "dynparam"
[149] "dynutils" "dynwrap"
[151] "e1071" "echarts4r"
[153] "editData" "elevatr"
[155] "ellipsis" "elliptic"
[157] "ellmer" "evaluate"
[159] "evd" "expm"
[161] "extraDistr" "extrafont"
[163] "extrafontdb" "f1dataR"
[165] "fable" "fable.prophet"
[167] "fabletools" "fansi"
[169] "farver" "fastmap"
[171] "feasts" "fields"
[173] "fiery" "filelock"
[175] "fireproof" "firesafety"
[177] "firesale" "firestorm"
[179] "flexiblas" "flextable"
[181] "float" "fmsb"
[183] "FNN" "fontawesome"
[185] "fontBitstreamVera" "fontLiberation"
[187] "fontquiver" "forcats"
[189] "foreach" "forecast"
[191] "foreign" "formatR"
[193] "formattable" "Formula"
[195] "fracdiff" "fredr"
[197] "fresh" "frontmatter"
[199] "fs" "furrr"
[201] "future" "future.apply"
[203] "fuzzyjoin" "gargle"
[205] "GauPro" "gdtools"
[207] "generics" "geodist"
[209] "geometries" "geometry"
[211] "geoR" "geosphere"
[213] "gert" "getPass"
[215] "gfonts" "GGally"
[217] "gganimate" "ggbeeswarm"
[219] "ggcorrplot" "ggdist"
[221] "ggExtra" "ggfittext"
[223] "ggforce" "ggfun"
[225] "gghighlight" "ggimage"
[227] "gginnards" "ggiraph"
[229] "ggplot2" "ggplotify"
[231] "ggpmisc" "ggpp"
[233] "ggpubr" "ggrepel"
[235] "ggridges" "ggsci"
[237] "ggsignif" "ggstats"
[239] "ggthemes" "ggtime"
[241] "gh" "ghclass"
[243] "ghclasspeer" "gifski"
[245] "gitcreds" "glarma"
[247] "glmnet" "GlobalOptions"
[249] "globals" "glue"
[251] "gmailr" "gmp"
[253] "googledrive" "googlePolylines"
[255] "googlesheets4" "gower"
[257] "GPArotation" "GPfit"
[259] "GpGp" "gptstudio"
[261] "graphics" "grDevices"
[263] "grid" "gridExtra"
[265] "gridGraphics" "gridtext"
[267] "gsubfn" "gt"
[269] "gtable" "gtfsio"
[271] "gtfsrouter" "gtfstools"
[273] "gtools" "hardhat"
[275] "hash" "haven"
[277] "here" "hexbin"
[279] "hexSticker" "highr"
[281] "histoslider" "Hmisc"
[283] "hms" "hrbrthemes"
[285] "htmlTable" "htmltools"
[287] "htmlwidgets" "httpcode"
[289] "httpuv" "httr"
[291] "httr2" "hypergeo"
[293] "ids" "igraph"
[295] "infer" "ini"
[297] "inline" "insight"
[299] "installr" "interp"
[301] "ipred" "isoband"
[303] "iterators" "janeaustenr"
[305] "janitor" "job"
[307] "jose" "jpeg"
[309] "jquerylib" "jsonlite"
[311] "jsonvalidate" "juicyjuice"
[313] "kableExtra" "kernlab"
[315] "KernSmooth" "knitr"
[317] "labeling" "labelled"
[319] "languageserver" "later"
[321] "latex2exp" "lattice"
[323] "latticeExtra" "lava"
[325] "lazyeval" "lbfgs"
[327] "leaflet" "leaflet.extras"
[329] "leaflet.extras2" "leaflet.providers"
[331] "leafpop" "LearnBayes"
[333] "learnr" "lgr"
[335] "lhs" "lifecycle"
[337] "lightgbm" "linprog"
[339] "lintr" "listenv"
[341] "litedown" "lme4"
[343] "lmodel2" "lmtest"
[345] "lobstr" "logger"
[347] "loo" "lookup"
[349] "lorem" "lpSolve"
[351] "lpSolveAPI" "lubridate"
[353] "lutz" "luz"
[355] "lwgeom" "magic"
[357] "magick" "magrittr"
[359] "mapiso" "mapproj"
[361] "maps" "marginaleffects"
[363] "markdown" "markermd"
[365] "marquee" "MASS"
[367] "Matrix" "MatrixExtra"
[369] "MatrixModels" "matrixStats"
[371] "maxLik" "mc2d"
[373] "mclust" "mcptools"
[375] "md4r" "measurements"
[377] "memoise" "methods"
[379] "Metrics" "mgcv"
[381] "microbenchmark" "mime"
[383] "miniUI" "minqa"
[385] "mirai" "miscTools"
[387] "mitools" "mixopt"
[389] "mixtools" "mlapi"
[391] "mlbench" "mlbplotR"
[393] "mnormt" "mockery"
[395] "modeldata" "modelenv"
[397] "ModelMetrics" "modelr"
[399] "modeltools" "moonBook"
[401] "mosaicData" "multcomp"
[403] "multcompView" "munsell"
[405] "mvtnorm" "nabor"
[407] "naniar" "nanonext"
[409] "nanoparquet" "ncdf4"
[411] "nleqslv" "nlme"
[413] "nloptr" "NLP"
[415] "nnet" "nngeo"
[417] "norm" "nortest"
[419] "numDeriv" "nycflights13"
[421] "officer" "openai"
[423] "openintro" "openssl"
[425] "openxlsx" "oskeyring"
[427] "osrm" "otel"
[429] "packrat" "padr"
[431] "pagedown" "pak"
[433] "paletteer" "palmerpenguins"
[435] "pander" "pandoc"
[437] "parallel" "parallelly"
[439] "parsedate" "parsermd"
[441] "parsnip" "patchwork"
[443] "paws" "paws.analytics"
[445] "paws.application.integration" "paws.common"
[447] "paws.compute" "paws.cost.management"
[449] "paws.customer.engagement" "paws.database"
[451] "paws.developer.tools" "paws.end.user.computing"
[453] "paws.machine.learning" "paws.management"
[455] "paws.networking" "paws.security.identity"
[457] "paws.storage" "pbapply"
[459] "pbkrtest" "pcaPP"
[461] "pdftools" "pdist"
[463] "PerformanceAnalytics" "pillar"
[465] "pingr" "pins"
[467] "pkgbuild" "pkgcache"
[469] "pkgconfig" "pkgdepends"
[471] "pkgdown" "pkgload"
[473] "pkgsearch" "PKI"
[475] "plotly" "plumber"
[477] "plumber2" "plyr"
[479] "png" "pointblank"
[481] "polite" "polyclip"
[483] "polynom" "posterior"
[485] "pracma" "praise"
[487] "prettyunits" "prismatic"
[489] "pROC" "processx"
[491] "prodlim" "productplots"
[493] "profmem" "profvis"
[495] "progress" "progressr"
[497] "promises" "prophet"
[499] "proto" "proxy"
[501] "proxyC" "ps"
[503] "pscl" "psych"
[505] "purrr" "pyinit"
[507] "q2r" "qpdf"
[509] "quadprog" "qualtRics"
[511] "quantmod" "quantreg"
[513] "quarto" "queryparser"
[515] "QuickJSR" "quickr"
[517] "R.cache" "R.methodsS3"
[519] "R.oo" "R.utils"
[521] "R6" "ragg"
[523] "randomForest" "randomNames"
[525] "ranger" "RANN"
[527] "rapidoc" "RApiSerialize"
[529] "rappdirs" "rapportools"
[531] "raster" "rasterVis"
[533] "ratelimitr" "rbibutils"
[535] "rcmdcheck" "RColorBrewer"
[537] "Rcpp" "RcppArmadillo"
[539] "RcppEigen" "RcppInt64"
[541] "RcppParallel" "RcppProgress"
[543] "RcppRoll" "RcppSimdJson"
[545] "RcppTOML" "RCurl"
[547] "Rdpack" "rdtools"
[549] "reactable" "reactlog"
[551] "reactR" "readr"
[553] "readxl" "recipes"
[555] "reclin2" "reformulas"
[557] "registry" "rematch"
[559] "rematch2" "remotes"
[561] "renderthis" "renv"
[563] "repr" "reprex"
[565] "repurrrsive" "reqres"
[567] "reshape" "reshape2"
[569] "reticulate" "rex"
[571] "rextendr" "RhpcBLASctl"
[573] "rhub" "rio"
[575] "rjags" "rJava"
[577] "rjson" "rlang"
[579] "rmarkdown" "Rmpfr"
[581] "rnaturalearth" "rnaturalearthdata"
[583] "robotstxt" "RobStatTM"
[585] "robustbase" "ROI"
[587] "ROI.plugin.lpsolve" "routr"
[589] "roxygen2" "rpart"
[591] "rpart.plot" "rprojroot"
[593] "rrcov" "rrtable"
[595] "rsample" "rsconnect"
[597] "rscontract" "rsparse"
[599] "RSQLite" "rstan"
[601] "rstanarm" "rstantools"
[603] "rstatix" "rstudioapi"
[605] "Rttf2pt1" "rversions"
[607] "rvest" "rvg"
[609] "s2" "S7"
[611] "safetensors" "sandwich"
[613] "sass" "scales"
[615] "secretbase" "segmented"
[617] "selectr" "servr"
[619] "sessioninfo" "sets"
[621] "sf" "sfd"
[623] "sfdep" "sfheaders"
[625] "shades" "shape"
[627] "shiny" "shiny.blueprint"
[629] "shiny.i18n" "shiny.react"
[631] "shinyBS" "shinybusy"
[633] "shinychat" "shinycssloaders"
[635] "shinydashboard" "shinyFeedback"
[637] "shinyjs" "shinylive"
[639] "shinystan" "shinytest2"
[641] "shinythemes" "shinyvalidate"
[643] "shinyWidgets" "showimage"
[645] "showtext" "showtextdb"
[647] "sjlabelled" "sjmisc"
[649] "skimr" "slam"
[651] "slider" "slippymath"
[653] "sloop" "snakecase"
[655] "SnowballC" "snowflakeauth"
[657] "sodium" "sourcetools"
[659] "sp" "spam"
[661] "spaMM" "SparseM"
[663] "sparsevctrs" "spatial"
[665] "spatialreg" "spBayes"
[667] "spData" "spdep"
[669] "spiderbar" "splancs"
[671] "splines" "splitfngr"
[673] "splus2R" "spNNGP"
[675] "sportyR" "spotifyr"
[677] "sqldf" "SQUAREM"
[679] "SSEparser" "StanHeaders"
[681] "stars" "starsExtra"
[683] "Stat2Data" "statebins"
[685] "StatMatch" "stats"
[687] "stats4" "statsr"
[689] "storr" "stringdist"
[691] "stringfish" "stringi"
[693] "stringr" "styler"
[695] "summarytools" "survey"
[697] "survival" "svglite"
[699] "svUnit" "swagger"
[701] "sys" "sysfonts"
[703] "systemfonts" "syuzhet"
[705] "tailor" "targets"
[707] "taylor" "tcltk"
[709] "tensorA" "terra"
[711] "testthat" "text2vec"
[713] "textrecipes" "textshape"
[715] "textshaping" "textutils"
[717] "TH.data" "thematic"
[719] "threejs" "tibble"
[721] "tidybayes" "tidymodels"
[723] "tidyquant" "tidyquery"
[725] "tidyr" "tidyselect"
[727] "tidytext" "tidytransit"
[729] "tidyverse" "tiff"
[731] "tigris" "timechange"
[733] "timeDate" "timetk"
[735] "tinytex" "tm"
[737] "tokenizers" "tomledit"
[739] "tools" "toOrdinal"
[741] "topicmodels" "torch"
[743] "torchvision" "transformr"
[745] "translations" "treesitter.r"
[747] "triangle" "triebeard"
[749] "truncdist" "truncnorm"
[751] "tseries" "tsfeatures"
[753] "tsibble" "tsibbledata"
[755] "TTR" "tune"
[757] "tutorial.helpers" "tweenr"
[759] "tzdb" "udpipe"
[761] "ukbabynames" "units"
[763] "unvotes" "UpSetR"
[765] "urca" "urlchecker"
[767] "urltools" "usdata"
[769] "usethis" "usmap"
[771] "usmapdata" "utf8"
[773] "utils" "uuid"
[775] "V8" "vcd"
[777] "vctrs" "vipor"
[779] "viridis" "viridisLite"
[781] "visdat" "visNetwork"
[783] "vroom" "waiter"
[785] "waldo" "warp"
[787] "waysign" "weathR"
[789] "webr" "webshot"
[791] "webshot2" "websocket"
[793] "webutils" "whisker"
[795] "whoami" "withr"
[797] "wk" "wordcloud"
[799] "wordcloud2" "workflows"
[801] "workflowsets" "writexl"
[803] "xaringan" "xaringanExtra"
[805] "xfun" "xkcd"
[807] "XML" "xml2"
[809] "xmlparsedata" "xopen"
[811] "xtable" "xts"
[813] "yaml" "yaml12"
[815] "yardstick" "yesno"
[817] "yulab.utils" "zeallot"
[819] "zip" "zoo"
[821] "ztable"
.libPaths() will usually report (at least) two library locations:
System library - contains the base and recommended packages (e.g. stats, utils, MASS, etc.). Shared by all users of a machine - on shared systems (like the DSS servers) it is read-only and maintained by the administrators.
User library - belongs to you and is where packages you install will end up. The path is specific to both your user account and the minor version of R (e.g. 4.6)
Generally packages come from somewhere on the internet, most commonly from CRAN or GitHub; the methods for installing from these locations are slightly different.
Packages only need to be installed once (per R version), but must be loaded in every new R session where you want to use them.
The Comprehensive R Archive Network is the central repository of R packages.
Maintained by the R Foundation and run by a team of volunteers, ~23k packages
Contains all current versions of released packages as well as previous releases (including archived packages)
Similar in spirit to Perl’s CPAN, TeX’s CTAN, and Python’s PyPI
Some important features:
All submissions are reviewed by humans + automated checks
Strictly enforced submission policies and package requirements
All packages must be actively maintained and support upstream and downstream changes
pak is a modern replacement for install.packages() and remotes::install_github() developed by the open source team at Posit.
Fast - resolves, downloads, and installs packages in parallel (with caching)
One interface for many sources - CRAN, Bioconductor, GitHub, URLs, local files, etc.
Plans the full installation up front - shows what will be installed and catches dependency conflicts before anything is changed
Can find and install needed system dependencies (e.g. system libraries on Linux servers)
Python’s packaging ecosystem has historically been fragmented:
pip, virtualenv, venv, conda, poetry, pipenv, etc.requirements.txt, setup.py, pyproject.toml, etc.pyenv)uv is a modern tool that aims to unify these concerns with a fast, Rust-based implementation.
uv is a Python package and project manager developed by Astral (creators of ruff and recent OpenAI acquisition)
Key features:
pyproject.tomlpip and virtualenvThe Python Package Index is the central repository of Python packages.
Maintained by the Python Software Foundation and run by volunteers, ~880k projects
Contains all released versions of packages, as source distributions (sdists) and/or prebuilt binaries (wheels)
Some important differences from CRAN:
No review process - anyone with an account can upload a package (name squatting and malicious packages are a recurring problem)
No requirement that packages build, pass checks, or be actively maintained
No requirement that packages stay compatible with newer versions of their dependencies (or vice versa) - version conflicts between packages are common
Package quality, documentation, and upkeep vary widely - it is up to you to vet what you install
uv is already installed on the departmental servers; for local installs:
On MacOS/Linux:
or with Homebrew:
or with pip / pipx:
Once installed you should be able to run the following,
As long as you have version 0.12.* you should be fine.
uv can install and manage multiple Python versions,
cpython-3.15.0rc1-macos-aarch64-none <download available>
cpython-3.15.0rc1+freethreaded-macos-aarch64-none <download available>
cpython-3.14.7-macos-aarch64-none /opt/homebrew/bin/python3.14 -> ../Cellar/python@3.14/3.14.7/bin/python3.14
cpython-3.14.7-macos-aarch64-none /opt/homebrew/bin/python3 -> ../Cellar/python@3.14/3.14.7/bin/python3
cpython-3.14.7-macos-aarch64-none /Users/rundel/.local/bin/python3.14 -> /Users/rundel/.local/share/uv/python/cpython-3.14.7-macos-aarch64-none/bin/python3.14
cpython-3.14.7-macos-aarch64-none /Users/rundel/.local/share/uv/python/cpython-3.14-macos-aarch64-none/bin/python3.14
cpython-3.14.7+freethreaded-macos-aarch64-none <download available>
cpython-3.14.2-macos-aarch64-none /Users/rundel/.local/share/uv/python/cpython-3.14.2-macos-aarch64-none/bin/python3.14
cpython-3.13.15-macos-aarch64-none <download available>
cpython-3.13.15+freethreaded-macos-aarch64-none <download available>
cpython-3.12.14-macos-aarch64-none /opt/homebrew/bin/python3.12 -> ../Cellar/python@3.12/3.12.14/bin/python3.12
cpython-3.12.14-macos-aarch64-none <download available>
cpython-3.12.0-macos-aarch64-none /Users/rundel/.local/share/uv/python/cpython-3.12-macos-aarch64-none/bin/python3.12
cpython-3.11.16-macos-aarch64-none <download available>
cpython-3.10.21-macos-aarch64-none <download available>
...
The pinned version is stored in a .python-version file and will be used automatically for that directory (and its subdirectories).
Use uv init to create a new project,
Initialized project `my-project`
total 24
drwxr-xr-x@ 8 rundel wheel 256 Aug 23 22:47 .
drwx------@ 3 rundel wheel 96 Aug 23 22:47 ..
drwxr-xr-x@ 9 rundel wheel 288 Aug 23 22:47 .git
-rw-r--r--@ 1 rundel wheel 109 Aug 23 22:47 .gitignore
-rw-r--r--@ 1 rundel wheel 5 Aug 23 22:47 .python-version
-rw-r--r--@ 1 rundel wheel 0 Aug 23 22:47 README.md
-rw-r--r--@ 1 rundel wheel 361 Aug 23 22:47 pyproject.toml
drwxr-xr-x@ 3 rundel wheel 96 Aug 23 22:47 src
This creates a pyproject.toml, a minimal package skeleton in src/ (with a main() entry point), a README.md, and basic git infrastructure. Generally, we only really care about the pyproject.toml, which we can generate on its own via uv init --bare.
pyproject.tomlModern project metadata file, tracks the Python version and package dependencies among other details.
[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "Colin Rundel", email = "rundel@gmail.com" }
]
requires-python = ">=3.14"
dependencies = []
[project.scripts]
my-project = "my_project:main"
[build-system]
requires = ["uv_build>=0.12.5,<0.13.0"]
build-backend = "uv_build"Once we have our project set up, we can add (and install) dependencies directly via uv. uv add updates pyproject.toml and installs the package (creating a venv if needed).
Using CPython 3.14.2
Creating virtual environment at: .venv
Resolved 2 packages in 157ms
Installed 1 package in 27ms
+ numpy==2.4.1
Resolved 18 packages in 490ms
Prepared 5 packages in 9.18s
Installed 15 packages in 134ms
+ contourpy==1.3.3
+ cycler==0.12.1
+ fonttools==4.61.1
+ joblib==1.5.3
+ kiwisolver==1.4.9
+ matplotlib==3.10.8
+ packaging==25.0
+ pandas==3.0.0
+ pillow==12.1.0
+ pyparsing==3.3.2
+ python-dateutil==2.9.0.post0
+ scikit-learn==1.8.0
+ scipy==1.17.0
+ six==1.17.0
+ threadpoolctl==3.6.0
Resolved 26 packages in 336ms
Prepared 1 package in 238ms
Installed 2 packages in 3ms
+ pydantic==1.10.26
+ typing-extensions==4.15.0
Resolved 24 packages in 337ms
Prepared 4 packages in 859ms
Installed 5 packages in 27ms
+ iniconfig==2.3.0
+ pluggy==1.6.0
+ pygments==2.19.2
+ pytest==9.0.2
+ ruff==0.14.13
pyproject.toml[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "Colin Rundel", email = "rundel@gmail.com" }
]
requires-python = ">=3.14"
dependencies = [
"matplotlib>=3.10.8",
"numpy>=2.4.1",
"pandas>=3.0.0",
"pydantic<2",
"scikit-learn>=1.8.0",
]
[project.scripts]
my-project = "my_project:main"
[dependency-groups]
dev = [
"pytest>=9.0.2",
"ruff>=0.14.13",
]
[build-system]
requires = ["uv_build>=0.12.5,<0.13.0"]
build-backend = "uv_build"Virtual environments isolate project dependencies from the system Python and other projects. Packages are installed in a local folder in your project.
As we just saw, using uv add will create a new virtual environment in .venv by default if there is not an existing venv.
To explicitly create your own venv you can use,
To use the virtual environment certain environment variables need to be set correctly (e.g. PATH, PYTHONPATH, etc.) so that the correct Python binary and libraries are used.
From the command line / terminal you can run the following in your project directory:
Alternatively (strongly recommended), use uv run to execute commands in the environment without activating,
uv syncSince the .venv folder is system-specific (and large) it is not typically committed to git. Instead you will likely clone a repository that just has a pyproject.toml file.
Use uv sync to construct the venv and install all dependencies for the project
Using CPython 3.14.2
Creating virtual environment at: .venv
Resolved 26 packages in 8ms
Installed 23 packages in 96ms
+ contourpy==1.3.3
+ cycler==0.12.1
+ fonttools==4.61.1
+ iniconfig==2.3.0
+ joblib==1.5.3
+ kiwisolver==1.4.9
+ matplotlib==3.10.8
+ numpy==2.4.1
+ packaging==25.0
+ pandas==3.0.0
+ pillow==12.1.0
+ pluggy==1.6.0
...
New project setup:
Positron automatically detects virtual environments in your project directory. When you open a folder containing a .venv directory (created by uv), Positron will:
If not automatically detected, you can manually select the interpreter via the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and searching for “Python: Select Interpreter”.
Sta 523 - Fall 2026