Quick keys
— Navigate with ← → or spacebar.
F
fullscreen ·
S
speaker view ·
O
overview ·
Alt+Click
zoom
Navigation
×
# Python Environments for Machine Learning <!-- .slide: data-background-gradient="linear-gradient(135deg, rgba(2,132,199,0.13) 0%, rgba(16,185,129,0.10) 48%, rgba(249,115,22,0.10) 100%)" --> <div style="margin-top: 1.8em; text-align: center; opacity: 0.9;"> The annual summer AI Research Experience (AIRE) 2026. </div> <div style="margin-top: 1.4em; display: flex; justify-content: center; gap: 1.2rem; flex-wrap: wrap;"> <div style="display: flex; align-items: center; gap: 0.55rem; padding: 0.6rem 0.85rem; border-radius: 999px; background: rgba(2,132,199,0.10); border: 1px solid rgba(2,132,199,0.22);"> <img src="/assets/slides/2026-05-21-python-env/pip-icon.svg" alt="" aria-hidden="true" style="height: 24px; width: 24px; object-fit: contain;" /> <div style="font-weight: 650; color: rgba(2,132,199,0.95);">pip</div> </div> <div style="display: flex; align-items: center; gap: 0.55rem; padding: 0.6rem 0.85rem; border-radius: 999px; background: rgba(67,176,42,0.10); border: 1px solid rgba(67,176,42,0.26);"> <img src="/assets/slides/2026-05-21-python-env/conda-icon.svg" alt="" aria-hidden="true" style="height: 24px; width: 24px; object-fit: contain;" /> <div style="font-weight: 650; color: rgba(35,132,32,0.95);">Conda</div> </div> <div style="display: flex; align-items: center; gap: 0.55rem; padding: 0.6rem 0.85rem; border-radius: 999px; background: rgba(222,95,233,0.10); border: 1px solid rgba(222,95,233,0.24);"> <img src="/assets/slides/2026-05-21-python-env/uv-icon.svg" alt="" aria-hidden="true" style="height: 24px; width: 24px; object-fit: contain;" /> <div style="font-weight: 650; color: rgba(166,44,180,0.95);">uv</div> </div> </div> <div style="margin-top: 2.0em; opacity: 0.75; font-size: 0.85em; text-align: center;"> Mohsen Hariri - May 21, 2026 </div> <div style="text-align: center; margin-top: 2.2em;"> <div style="display: flex; align-items: center; justify-content: center; gap: 2.2rem; flex-wrap: wrap;"> <img src="/assets/slides/2026-01-16-state-of-llms/logo/cwru_logo.webp" alt="CWRU" style="height: 70px; width: auto; padding: 0.3em 0.4em;" /> <img src="/assets/slides/2026-01-16-state-of-llms/logo/uoc_logo.webp" alt="University of Cincinnati" style="height: 70px; width: auto; padding: 0.3em 0.4em;" /> <img src="/assets/slides/2026-01-16-state-of-llms/logo/osu_logo.webp" alt="Ohio State University" style="height: 70px; width: auto; padding: 0.3em 0.4em;" /> <img src="/assets/slides/2026-01-16-state-of-llms/logo/NSF_Official_logo_Low_Res_150ppi-300x300.webp" alt="NSF" style="height: 70px; width: auto; padding: 0.3em 0.4em;" /> </div> </div> --- <style> :root { --env-blue: rgb(2, 132, 199); --env-green: rgb(5, 150, 105); --env-orange: rgb(194, 65, 12); --env-slate: rgb(15, 23, 42); --env-muted: rgba(15, 23, 42, 0.72); --env-border: rgba(15, 23, 42, 0.14); --env-card: rgba(255, 255, 255, 0.74); } .reveal .slides { text-align: left; } .reveal h1, .reveal h2, .reveal h3 { text-align: left; letter-spacing: 0; } .reveal h1 { text-align: center; font-size: 2.05em; line-height: 1.08; } .reveal p, .reveal li { line-height: 1.36; } .reveal strong { font-weight: 700; } .reveal code { font-size: 0.86em; } .reveal .env-subtitle { margin-top: 1.2rem; text-align: center; font-size: 0.92em; color: var(--env-muted); } .reveal .env-meta, .reveal .env-foot { margin-top: 1.8rem; text-align: center; font-size: 0.76em; color: var(--env-muted); } .reveal .env-foot { margin-top: 1.35rem; font-size: 0.62em; } .reveal .env-logo-row { display: flex; align-items: center; justify-content: center; gap: 2rem; flex-wrap: wrap; } .reveal .env-logo-row img { height: 66px; width: auto; max-width: 210px; object-fit: contain; } .reveal .env-chip-row { display: flex; justify-content: center; gap: 0.75rem; flex-wrap: wrap; } .reveal .env-chip { display: inline-flex; align-items: center; border-radius: 999px; padding: 0.34rem 0.68rem; border: 1px solid var(--env-border); background: rgba(255, 255, 255, 0.72); font-size: 0.56em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; } .reveal .env-chip.blue { color: var(--env-blue); border-color: rgba(2,132,199,0.28); background: rgba(2,132,199,0.09); } .reveal .env-chip.green { color: var(--env-green); border-color: rgba(5,150,105,0.28); background: rgba(5,150,105,0.09); } .reveal .env-chip.orange { color: var(--env-orange); border-color: rgba(194,65,12,0.28); background: rgba(249,115,22,0.09); } .reveal .env-chip.slate { color: var(--env-slate); background: rgba(15,23,42,0.06); } .reveal .env-grid { display: grid; gap: 1rem; margin-top: 1rem; } .reveal .env-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); } .reveal .env-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); } .reveal .env-grid.four { grid-template-columns: repeat(4, minmax(0, 1fr)); } .reveal .env-card { border: 1px solid var(--env-border); border-radius: 8px; background: var(--env-card); padding: 0.86rem 0.96rem; box-shadow: 0 10px 26px rgba(15, 23, 42, 0.06); } .reveal .env-card h3 { margin: 0 0 0.42rem 0; font-size: 0.82em; } .reveal .env-card p { margin: 0; color: var(--env-muted); font-size: 0.68em; } .reveal .env-card ul { margin: 0.45rem 0 0 0; padding-left: 1.1rem; font-size: 0.68em; } .reveal .env-card li { margin: 0.18rem 0; } .reveal .env-kicker { font-size: 0.5em; text-transform: uppercase; letter-spacing: 0.08em; color: var(--env-muted); margin-bottom: 0.25rem; } .reveal .env-callout { border-left: 5px solid var(--env-blue); border-radius: 8px; background: rgba(2,132,199,0.07); padding: 0.82rem 0.95rem; margin-top: 1rem; font-size: 0.74em; } .reveal .env-callout.green { border-left-color: var(--env-green); background: rgba(5,150,105,0.08); } .reveal .env-callout.orange { border-left-color: var(--env-orange); background: rgba(249,115,22,0.08); } .reveal .env-pre { margin: 0.58rem 0 0 0; padding: 0.72rem 0.82rem; border-radius: 8px; border: 1px solid rgba(15,23,42,0.12); background: rgba(15,23,42,0.06); font-size: 0.52em; line-height: 1.3; white-space: pre-wrap; } .reveal .env-table { width: 100%; border-collapse: collapse; margin-top: 1rem; font-size: 0.62em; } .reveal .env-table th, .reveal .env-table td { border-bottom: 1px solid rgba(15,23,42,0.12); padding: 0.58rem 0.5rem; vertical-align: top; } .reveal .env-table th { color: var(--env-slate); font-weight: 700; } .reveal .env-table td { color: var(--env-muted); } .reveal .env-cheat { --tool-rgb: 2, 132, 199; --tool-ink: rgb(2, 132, 199); display: grid; grid-template-columns: 13.4rem minmax(0, 1fr); min-height: 27.8rem; margin-top: 0.62rem; overflow: hidden; border: 1px solid rgba(15,23,42,0.14); border-radius: 8px; background: linear-gradient(90deg, rgba(15,23,42,0.04) 1px, transparent 1px), linear-gradient(0deg, rgba(15,23,42,0.035) 1px, transparent 1px), linear-gradient(135deg, rgba(var(--tool-rgb),0.08), rgba(255,255,255,0.78) 42%, rgba(15,23,42,0.035)); background-size: 30px 30px, 30px 30px, auto; box-shadow: 0 16px 34px rgba(15,23,42,0.09); } .reveal .env-cheat.conda { --tool-rgb: 67, 176, 42; --tool-ink: rgb(35, 132, 32); } .reveal .env-cheat.uv { --tool-rgb: 166, 44, 180; --tool-ink: rgb(166, 44, 180); } .reveal .env-cheat-rail { display: flex; flex-direction: column; gap: 0.68rem; padding: 1.05rem; border-right: 1px solid rgba(15,23,42,0.12); background: linear-gradient(180deg, rgba(var(--tool-rgb),0.14), rgba(255,255,255,0.62)); } .reveal .env-cheat-logo { width: 3.45rem; height: 3.45rem; padding: 0.52rem; object-fit: contain; border-radius: 8px; border: 1px solid rgba(var(--tool-rgb),0.24); background: rgba(255,255,255,0.82); } .reveal .env-cheat-kicker { margin-top: 0.3rem; color: var(--env-muted); font-size: 0.45em; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; } .reveal .env-cheat-rail h3 { margin: -0.15rem 0 0 0; color: var(--tool-ink); font-size: 1.42em; line-height: 0.96; } .reveal .env-cheat-rail p { margin: 0; color: var(--env-muted); font-size: 0.58em; line-height: 1.32; } .reveal .env-cheat-files { display: grid; gap: 0.44rem; margin-top: auto; } .reveal .env-file-pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.12rem; align-items: center; padding: 0.38rem 0.46rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 8px; background: rgba(255,255,255,0.70); } .reveal .env-file-pair span { color: var(--env-muted); font-size: 0.42em; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; } .reveal .env-file-pair code { font-size: 0.40em; overflow-wrap: normal; white-space: nowrap; } .reveal .env-cheat-main { display: grid; grid-template-rows: auto auto auto; align-content: start; gap: 0.54rem; padding: 0.82rem; } .reveal .env-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.52rem; } .reveal .env-flow-card { position: relative; min-height: 6.6rem; padding: 0.58rem 0.56rem 0.55rem; border: 1px solid rgba(15,23,42,0.11); border-top: 4px solid var(--tool-ink); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-step { position: absolute; right: 0.5rem; top: 0.42rem; color: rgba(var(--tool-rgb),0.30); font-size: 0.58em; font-weight: 900; } .reveal .env-flow-card strong { display: block; max-width: 82%; margin-bottom: 0.42rem; color: var(--env-slate); font-size: 0.54em; line-height: 1.14; } .reveal .env-flow-card code, .reveal .env-terminal code, .reveal .env-rule code { white-space: pre-wrap; overflow-wrap: anywhere; } .reveal .env-flow-card code { display: block; padding: 0.4rem 0.44rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 7px; background: rgba(15,23,42,0.055); font-size: 0.43em; line-height: 1.24; } .reveal .env-command-bank { display: grid; grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr); gap: 0.6rem; } .reveal .env-terminal { margin: 0; min-height: 10rem; padding: 0.68rem 0.76rem; border: 1px solid rgba(15,23,42,0.18); border-radius: 8px; background: rgba(15,23,42,0.92); color: rgb(226,232,240); font-size: 0.49em; line-height: 1.28; } .reveal .env-terminal code { color: inherit; background: transparent; } .reveal .env-dos { display: grid; align-content: start; gap: 0.48rem; } .reveal .env-do { display: grid; grid-template-columns: 6.3rem minmax(0, 1fr); gap: 0.45rem; align-items: start; min-height: 2.9rem; padding: 0.48rem 0.54rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 8px; background: rgba(255,255,255,0.76); font-size: 0.55em; line-height: 1.28; } .reveal .env-do strong { color: var(--tool-ink); font-weight: 850; } .reveal .env-cheat-footer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.44rem; } .reveal .env-rule { min-height: 2.85rem; padding: 0.42rem 0.54rem; border: 1px solid rgba(var(--tool-rgb),0.20); border-radius: 8px; background: rgba(var(--tool-rgb),0.075); font-size: 0.49em; line-height: 1.24; } .reveal .env-rule strong { display: block; margin-bottom: 0.22rem; color: var(--tool-ink); font-size: 0.9em; text-transform: uppercase; letter-spacing: 0.04em; } .reveal .env-rule code { display: block; font-size: 0.88em; line-height: 1.22; } .reveal .env-debug-board { display: grid; grid-template-columns: 12.6rem minmax(0, 1fr); gap: 0; margin-top: 0.7rem; overflow: hidden; border: 1px solid rgba(15,23,42,0.14); border-radius: 8px; background: linear-gradient(90deg, rgba(194,65,12,0.035) 1px, transparent 1px), linear-gradient(0deg, rgba(15,23,42,0.035) 1px, transparent 1px), rgba(255,255,255,0.84); background-size: 30px 30px; box-shadow: 0 18px 36px rgba(15,23,42,0.08); } .reveal .env-debug-rail { display: flex; flex-direction: column; gap: 0.72rem; padding: 1rem; border-right: 1px solid rgba(194,65,12,0.18); background: linear-gradient(180deg, rgba(249,115,22,0.16), rgba(255,255,255,0.70)); } .reveal .env-debug-badge { width: 3.1rem; height: 3.1rem; display: grid; place-items: center; border: 1px solid rgba(194,65,12,0.26); border-radius: 8px; background: rgba(255,255,255,0.86); color: var(--env-orange); font-size: 0.58em; font-weight: 900; letter-spacing: 0.04em; } .reveal .env-debug-rail h3 { margin: 0.15rem 0 0 0; color: var(--env-orange); font-size: 0.94em; line-height: 1.05; } .reveal .env-debug-rail p { margin: 0; color: var(--env-muted); font-size: 0.56em; line-height: 1.34; } .reveal .env-debug-chipset { display: grid; gap: 0.42rem; margin-top: auto; } .reveal .env-debug-chip { padding: 0.42rem 0.5rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 8px; background: rgba(255,255,255,0.74); color: var(--env-muted); font-size: 0.43em; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; } .reveal .env-debug-main { display: grid; gap: 0.7rem; padding: 0.86rem; } .reveal .env-debug-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.62rem; } .reveal .env-debug-card { position: relative; min-height: 15.4rem; padding: 0.78rem; border: 1px solid rgba(15,23,42,0.12); border-top: 4px solid var(--env-orange); border-radius: 8px; background: rgba(255,255,255,0.82); } .reveal .env-debug-num { position: absolute; right: 0.68rem; top: 0.48rem; color: rgba(194,65,12,0.28); font-size: 0.74em; font-weight: 900; } .reveal .env-debug-card h3 { max-width: 80%; margin: 0 0 0.54rem 0; color: var(--env-slate); font-size: 0.68em; line-height: 1.12; } .reveal .env-debug-terminal { display: grid; gap: 0.32rem; margin: 0; padding: 0.68rem 0.74rem; border: 1px solid rgba(15,23,42,0.18); border-radius: 8px; background: rgba(15,23,42,0.93); box-shadow: 0 10px 24px rgba(15,23,42,0.12); } .reveal .env-debug-terminal code { display: block; color: rgb(226,232,240); background: transparent; font-size: 0.43em; line-height: 1.24; white-space: normal; overflow-wrap: anywhere; } .reveal .env-debug-terminal code::before { content: "$ "; color: rgb(251,146,60); font-weight: 800; } .reveal .env-debug-card p { margin: 0.58rem 0 0 0; color: var(--env-muted); font-size: 0.54em; line-height: 1.3; } .reveal .env-debug-card strong { color: var(--env-orange); font-weight: 850; } .reveal .env-debug-bottom { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr); gap: 0.62rem; align-items: stretch; } .reveal .env-debug-callout { padding: 0.74rem 0.86rem; border-left: 5px solid var(--env-orange); border-radius: 8px; background: rgba(249,115,22,0.09); color: var(--env-slate); font-size: 0.62em; line-height: 1.28; } .reveal .env-debug-axis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.42rem; } .reveal .env-debug-axis span { display: grid; place-items: center; min-height: 2.7rem; padding: 0.32rem 0.4rem; border: 1px solid rgba(194,65,12,0.16); border-radius: 8px; background: rgba(255,255,255,0.78); color: var(--env-muted); font-size: 0.44em; font-weight: 800; letter-spacing: 0.05em; text-align: center; text-transform: uppercase; } .reveal .env-study-layout { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: 0.82rem; align-items: stretch; margin-top: 0.8rem; } .reveal .env-scipe-panel, .reveal .env-ref-panel { border: 1px solid rgba(15,23,42,0.14); border-radius: 8px; background: rgba(255,255,255,0.80); box-shadow: 0 14px 30px rgba(15,23,42,0.08); } .reveal .env-scipe-panel { display: grid; align-content: start; gap: 0.58rem; padding: 0.68rem; } .reveal .env-scipe-head { display: grid; grid-template-columns: 4.2rem minmax(0, 1fr); gap: 0.72rem; align-items: center; padding: 0.7rem; border-radius: 8px; background: linear-gradient(135deg, rgba(2,132,199,0.13), rgba(5,150,105,0.09)); border: 1px solid rgba(2,132,199,0.18); } .reveal .env-scipe-mark { display: grid; place-items: center; width: 4.2rem; height: 4.2rem; border-radius: 8px; background: rgb(15, 23, 42); color: white; font-size: 0.58em; font-weight: 900; letter-spacing: 0.04em; } .reveal .env-scipe-head h3 { margin: 0; color: var(--env-slate); font-size: 0.82em; line-height: 1.05; } .reveal .env-scipe-head p { margin: 0.25rem 0 0 0; color: var(--env-muted); font-size: 0.5em; line-height: 1.24; } .reveal .env-scipe-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; } .reveal .env-scipe-links a { display: grid; align-content: start; min-height: 6.2rem; padding: 0.58rem 0.62rem; border: 1px solid rgba(2,132,199,0.20); border-radius: 8px; background: rgba(2,132,199,0.07); color: rgb(3, 105, 161); text-decoration: none; } .reveal .env-scipe-links strong { color: rgb(3, 105, 161); font-size: 0.58em; line-height: 1.18; } .reveal .env-scipe-links span { margin-top: 0.26rem; color: var(--env-muted); font-size: 0.42em; line-height: 1.22; } .reveal .env-ref-panel { padding: 0.68rem; } .reveal .env-ref-panel h3 { margin: 0 0 0.62rem 0; font-size: 0.82em; } .reveal .env-ref-grid { display: grid; grid-template-columns: 1fr; gap: 0.52rem; } .reveal .env-ref-card { display: grid; grid-template-columns: 2.7rem minmax(0, 1fr); gap: 0.6rem; align-items: center; min-height: 3.85rem; padding: 0.55rem 0.62rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 8px; background: rgba(255,255,255,0.76); } .reveal .env-ref-logo { display: grid; place-items: center; width: 2.42rem; height: 2.42rem; border-radius: 8px; border: 1px solid rgba(15,23,42,0.12); background: rgba(15,23,42,0.045); color: var(--env-slate); font-size: 0.36em; font-weight: 900; letter-spacing: 0.03em; } .reveal .env-ref-logo img { max-width: 1.58rem; max-height: 1.58rem; object-fit: contain; } .reveal .env-ref-card a { display: block; color: rgb(2, 132, 199); font-size: 0.58em; font-weight: 800; line-height: 1.18; text-decoration: none; } .reveal .env-ref-card span { display: block; margin-top: 0.16rem; color: var(--env-muted); font-size: 0.44em; line-height: 1.18; overflow-wrap: anywhere; } .reveal .env-big { font-size: 1.18em; text-align: center; margin-top: 1.5rem; } .reveal .env-center { text-align: center; } .reveal .env-muted { color: var(--env-muted); } .reveal .slides section { box-sizing: border-box; } .reveal h2 { display: inline-block; padding-bottom: 0.18rem; } .reveal h2 + .env-section-note { margin-top: 0.3rem; } .reveal .env-section-note { max-width: 50rem; color: var(--env-muted); font-size: 0.66em; line-height: 1.32; } .reveal .env-cover-shell { display: grid; grid-template-columns: minmax(0, 1fr) 22rem; gap: 2.1rem; align-items: center; margin-top: 0.65rem; } .reveal .env-cover-copy { text-align: left; } .reveal .env-eyebrow { display: inline-flex; align-items: center; padding: 0.36rem 0.66rem; border: 1px solid rgba(2,132,199,0.22); border-radius: 999px; background: rgba(2,132,199,0.08); color: rgb(3,105,161); font-size: 0.48em; font-weight: 850; letter-spacing: 0.08em; text-transform: uppercase; } .reveal .env-cover-subtitle { margin: 0.9rem 0 0 0; color: var(--env-slate); font-size: 0.86em; line-height: 1.28; } .reveal .env-cover-meta { margin-top: 0.8rem; color: var(--env-muted); font-size: 0.58em; } .reveal .env-cover-pills { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 1.2rem; } .reveal .env-tool-pill { display: inline-flex; align-items: center; gap: 0.42rem; padding: 0.42rem 0.64rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 999px; background: rgba(255,255,255,0.76); color: var(--env-slate); font-size: 0.52em; font-weight: 850; letter-spacing: 0.03em; text-transform: uppercase; } .reveal .env-tool-pill img { width: 1.05rem; height: 1.05rem; object-fit: contain; } .reveal .env-tool-pill.pip { border-color: rgba(2,132,199,0.26); color: rgb(3,105,161); background: rgba(2,132,199,0.08); } .reveal .env-tool-pill.conda { border-color: rgba(67,176,42,0.30); color: rgb(35,132,32); background: rgba(67,176,42,0.10); } .reveal .env-tool-pill.uv { border-color: rgba(166,44,180,0.28); color: rgb(126,34,147); background: rgba(166,44,180,0.09); } .reveal .env-cover-map { position: relative; min-height: 16.8rem; border: 1px solid rgba(15,23,42,0.13); border-radius: 8px; background: linear-gradient(90deg, rgba(15,23,42,0.04) 1px, transparent 1px), linear-gradient(0deg, rgba(15,23,42,0.035) 1px, transparent 1px), rgba(255,255,255,0.72); background-size: 28px 28px, 28px 28px, auto; box-shadow: 0 18px 40px rgba(15,23,42,0.09); } .reveal .env-map-core, .reveal .env-map-lock, .reveal .env-map-ring span { position: absolute; display: grid; place-items: center; text-align: center; border-radius: 8px; border: 1px solid rgba(15,23,42,0.12); background: rgba(255,255,255,0.84); box-shadow: 0 8px 20px rgba(15,23,42,0.07); } .reveal .env-map-core { left: 50%; top: 50%; width: 7.2rem; height: 7.2rem; transform: translate(-50%, -50%); color: var(--env-slate); font-size: 0.68em; font-weight: 900; line-height: 1.06; border-color: rgba(2,132,199,0.30); background: linear-gradient(135deg, rgba(2,132,199,0.16), rgba(255,255,255,0.88)); } .reveal .env-map-core span { display: block; margin-top: 0.2rem; color: var(--env-muted); font-size: 0.64em; font-weight: 700; } .reveal .env-map-ring span { min-width: 5.4rem; min-height: 2.4rem; padding: 0.3rem 0.45rem; color: var(--env-slate); font-size: 0.46em; font-weight: 850; letter-spacing: 0.04em; text-transform: uppercase; } .reveal .ring-one span:nth-child(1) { left: 1.05rem; top: 3.2rem; border-color: rgba(2,132,199,0.24); background: rgba(2,132,199,0.08); } .reveal .ring-one span:nth-child(2) { right: 1.05rem; top: 3.2rem; border-color: rgba(67,176,42,0.24); background: rgba(67,176,42,0.09); } .reveal .ring-one span:nth-child(3) { left: 50%; bottom: 1.15rem; transform: translateX(-50%); border-color: rgba(194,65,12,0.24); background: rgba(249,115,22,0.08); } .reveal .ring-two span:nth-child(1) { left: 1.1rem; bottom: 6.2rem; color: rgb(3,105,161); } .reveal .ring-two span:nth-child(2) { right: 1.1rem; bottom: 6.2rem; color: rgb(35,132,32); } .reveal .ring-two span:nth-child(3) { left: 50%; top: 1.0rem; transform: translateX(-50%); color: rgb(126,34,147); } .reveal .env-map-lock { right: 1rem; bottom: 1rem; min-width: 6.9rem; min-height: 2.3rem; color: rgb(194,65,12); font-size: 0.48em; font-weight: 900; letter-spacing: 0.05em; text-transform: uppercase; border-color: rgba(194,65,12,0.24); background: rgba(249,115,22,0.09); } .reveal .env-logo-strip { display: flex; align-items: center; justify-content: center; gap: 1.3rem; flex-wrap: wrap; margin-top: 0.9rem; padding-top: 0.65rem; border-top: 1px solid rgba(15,23,42,0.10); } .reveal .env-logo-strip img { height: 3.1rem; width: auto; max-width: 10.5rem; object-fit: contain; } .reveal .env-roadmap { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.72rem; margin-top: 1rem; } .reveal .env-road-step { position: relative; min-height: 13.5rem; padding: 0.78rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.78); box-shadow: 0 12px 26px rgba(15,23,42,0.07); } .reveal .env-road-step::before { content: attr(data-step); display: grid; place-items: center; width: 2.35rem; height: 2.35rem; margin-bottom: 0.62rem; border-radius: 8px; background: rgba(15,23,42,0.92); color: white; font-size: 0.5em; font-weight: 900; } .reveal .env-road-step.blue::before { background: rgb(2,132,199); } .reveal .env-road-step.green::before { background: rgb(5,150,105); } .reveal .env-road-step.orange::before { background: rgb(194,65,12); } .reveal .env-road-step.purple::before { background: rgb(126,34,147); } .reveal .env-road-step h3 { margin: 0 0 0.42rem 0; font-size: 0.68em; line-height: 1.12; } .reveal .env-road-step p { margin: 0; color: var(--env-muted); font-size: 0.54em; line-height: 1.32; } .reveal .env-road-step code { font-size: 0.86em; } .reveal .env-compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.85rem; margin-top: 0.92rem; } .reveal .env-world { min-height: 25rem; padding: 0.86rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.78); box-shadow: 0 14px 30px rgba(15,23,42,0.07); } .reveal .env-world.bad { border-top: 5px solid var(--env-orange); } .reveal .env-world.good { border-top: 5px solid var(--env-green); } .reveal .env-world h3 { margin: 0 0 0.52rem 0; font-size: 0.76em; } .reveal .env-world ul, .reveal .env-mystery-panel ul { margin: 0.52rem 0 0 0; padding-left: 1.1rem; color: var(--env-muted); font-size: 0.62em; } .reveal .env-world li, .reveal .env-mystery-panel li { margin: 0.2rem 0; } .reveal .env-collision { position: relative; min-height: 11.7rem; margin: 0.56rem 0 0.7rem; border-radius: 8px; background: linear-gradient(90deg, rgba(15,23,42,0.05) 1px, transparent 1px), linear-gradient(0deg, rgba(15,23,42,0.04) 1px, transparent 1px), rgba(15,23,42,0.035); background-size: 26px 26px; } .reveal .env-collision span, .reveal .env-islands span { position: absolute; display: grid; place-items: center; min-width: 6.5rem; min-height: 2.4rem; padding: 0.26rem 0.42rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.88); color: var(--env-slate); font-size: 0.46em; font-weight: 850; line-height: 1.14; text-align: center; } .reveal .env-collision span:nth-child(1) { left: 1rem; top: 1rem; border-color: rgba(2,132,199,0.25); } .reveal .env-collision span:nth-child(2) { right: 1rem; top: 1rem; border-color: rgba(194,65,12,0.25); } .reveal .env-collision span:nth-child(3) { left: 50%; top: 4.75rem; transform: translateX(-50%); min-width: 8rem; background: rgba(249,115,22,0.12); border-color: rgba(194,65,12,0.30); color: rgb(154,52,18); } .reveal .env-collision span:nth-child(4) { left: 50%; bottom: 1rem; transform: translateX(-50%); border-color: rgba(15,23,42,0.18); } .reveal .env-islands { position: relative; min-height: 11.7rem; margin: 0.56rem 0 0.7rem; border-radius: 8px; background: linear-gradient(90deg, rgba(5,150,105,0.055) 1px, transparent 1px), linear-gradient(0deg, rgba(5,150,105,0.045) 1px, transparent 1px), rgba(5,150,105,0.045); background-size: 26px 26px; } .reveal .env-islands span:nth-child(1) { left: 1rem; top: 1rem; border-color: rgba(2,132,199,0.25); } .reveal .env-islands span:nth-child(2) { right: 1rem; top: 1rem; border-color: rgba(5,150,105,0.28); } .reveal .env-islands span:nth-child(3) { left: 1rem; bottom: 1rem; border-color: rgba(126,34,147,0.25); } .reveal .env-islands span:nth-child(4) { right: 1rem; bottom: 1rem; border-color: rgba(194,65,12,0.25); } .reveal .env-small-list { margin: 0.48rem 0 0 0; padding-left: 1.08rem; color: var(--env-muted); font-size: 0.58em; } .reveal .env-small-list li { margin: 0.2rem 0; } .reveal .env-formula { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5rem; align-items: stretch; margin-top: 0.95rem; } .reveal .env-formula span { display: grid; place-items: center; min-height: 3.8rem; padding: 0.38rem 0.48rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.78); color: var(--env-slate); font-size: 0.58em; font-weight: 850; text-align: center; } .reveal .env-formula span:nth-child(1) { border-color: rgba(2,132,199,0.26); background: rgba(2,132,199,0.08); } .reveal .env-formula span:nth-child(2) { border-color: rgba(5,150,105,0.26); background: rgba(5,150,105,0.08); } .reveal .env-formula span:nth-child(3) { border-color: rgba(126,34,147,0.24); background: rgba(166,44,180,0.08); } .reveal .env-formula span:nth-child(4) { border-color: rgba(194,65,12,0.24); background: rgba(249,115,22,0.08); } .reveal .env-stack-layout { display: grid; grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.12fr); gap: 0.78rem; align-items: stretch; margin-top: 0.9rem; } .reveal .env-stack { display: grid; gap: 0.48rem; padding: 0.75rem; border: 1px solid rgba(15,23,42,0.13); border-radius: 8px; background: rgba(255,255,255,0.78); box-shadow: 0 14px 30px rgba(15,23,42,0.07); } .reveal .env-stack-layer { display: grid; grid-template-columns: 2.6rem minmax(0, 1fr); gap: 0.58rem; align-items: center; min-height: 4.2rem; padding: 0.56rem 0.66rem; border: 1px solid rgba(15,23,42,0.11); border-radius: 8px; background: rgba(255,255,255,0.82); } .reveal .env-stack-num { display: grid; place-items: center; width: 2.35rem; height: 2.35rem; border-radius: 8px; background: rgba(15,23,42,0.92); color: white; font-size: 0.48em; font-weight: 900; } .reveal .env-stack-layer h3 { margin: 0; font-size: 0.62em; line-height: 1.12; } .reveal .env-stack-layer p { margin: 0.16rem 0 0 0; color: var(--env-muted); font-size: 0.46em; line-height: 1.22; } .reveal .env-lane-board { display: grid; gap: 0.62rem; } .reveal .env-lane { display: grid; grid-template-columns: 7.4rem minmax(0, 1fr) 14rem; gap: 0.55rem; align-items: stretch; padding: 0.62rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-lane strong { display: grid; place-items: center; border-radius: 8px; background: rgba(15,23,42,0.06); color: var(--env-slate); font-size: 0.58em; line-height: 1.08; padding: 0.34rem; text-align: center; } .reveal .env-lane > span, .reveal .env-lane > code { align-items: center; min-height: 3.15rem; padding: 0.44rem 0.5rem; border-radius: 8px; background: rgba(15,23,42,0.045); color: var(--env-muted); font-size: 0.56em; line-height: 1.18; } .reveal .env-lane > span { display: flex; flex-wrap: wrap; gap: 0.3rem; } .reveal .env-lane > code { display: grid; place-items: center start; color: var(--env-slate); white-space: normal; overflow-wrap: normal; word-break: normal; } .reveal .env-lane > span code, .reveal .env-lane > span em { display: inline-flex; align-items: center; min-height: 1.48rem; padding: 0.18rem 0.34rem; border-radius: 6px; background: rgba(255,255,255,0.78); color: var(--env-slate); font-size: 0.84em; font-style: normal; font-weight: 750; line-height: 1; white-space: nowrap; } .reveal .env-workflow-board { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(18rem, 0.92fr); gap: 0.9rem; align-items: stretch; margin-top: 0.72rem; } .reveal .env-step-board { display: grid; grid-template-columns: 1fr; gap: 0.46rem; padding: 0.66rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: linear-gradient(90deg, rgba(2,132,199,0.045) 1px, transparent 1px), linear-gradient(0deg, rgba(2,132,199,0.035) 1px, transparent 1px), rgba(255,255,255,0.78); background-size: 28px 28px, 28px 28px, auto; box-shadow: 0 14px 30px rgba(15,23,42,0.07); } .reveal .env-work-step { display: grid; grid-template-columns: 6.7rem minmax(0, 1fr); gap: 0.58rem; align-items: center; min-height: 3.35rem; padding: 0.52rem 0.58rem; border: 1px solid rgba(15,23,42,0.12); border-left: 5px solid rgb(2,132,199); border-radius: 8px; background: rgba(255,255,255,0.86); } .reveal .env-work-step:nth-child(2) { border-left-color: rgb(5,150,105); } .reveal .env-work-step:nth-child(3) { border-left-color: rgb(126,34,147); } .reveal .env-work-step:nth-child(4) { border-left-color: rgb(194,65,12); } .reveal .env-work-step > span { display: block; color: var(--env-muted); font-weight: 750; line-height: 1.16; } .reveal .env-work-step strong { display: block; color: var(--env-slate); font-size: 0.48em; line-height: 1.08; } .reveal .env-work-step em { display: block; margin-top: 0.12rem; color: var(--env-muted); font-size: 0.34em; font-style: normal; font-weight: 650; line-height: 1.16; } .reveal .env-work-step code { display: block; padding: 0.46rem 0.52rem; border-radius: 8px; background: rgba(15,23,42,0.92); color: rgb(226,232,240); font-size: 0.41em; line-height: 1.2; white-space: pre-wrap; overflow-wrap: anywhere; } .reveal .env-work-panel { display: grid; align-content: start; gap: 0.56rem; padding: 0.78rem 0.84rem; border: 1px solid rgba(2,132,199,0.18); border-radius: 8px; background: linear-gradient(135deg, rgba(2,132,199,0.10), rgba(255,255,255,0.78)); box-shadow: 0 14px 30px rgba(15,23,42,0.06); } .reveal .env-work-panel h3 { margin: 0; color: rgb(3,105,161); font-size: 0.72em; } .reveal .env-work-panel p { margin: 0; color: var(--env-muted); font-size: 0.54em; line-height: 1.3; } .reveal .env-use-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.38rem; } .reveal .env-use-list span { display: grid; align-content: center; min-height: 2.4rem; padding: 0.34rem 0.42rem; border: 1px solid rgba(2,132,199,0.16); border-radius: 8px; background: rgba(255,255,255,0.78); color: var(--env-slate); font-size: 0.4em; font-weight: 800; line-height: 1.15; text-align: center; } .reveal .env-file-flow { display: grid; grid-template-columns: 1fr; gap: 0.36rem; } .reveal .env-file-flow > span { display: grid; grid-template-columns: 6.2rem minmax(0, 1fr); gap: 0.48rem; align-items: center; min-height: 2.45rem; padding: 0.34rem 0.46rem; border: 1px solid rgba(2,132,199,0.18); border-radius: 8px; background: rgba(255,255,255,0.78); color: var(--env-slate); font-size: 0.42em; font-weight: 850; line-height: 1.16; } .reveal .env-file-flow > span > span { min-width: 0; } .reveal .env-file-flow b { color: rgb(3,105,161); font-size: 0.78em; letter-spacing: 0.06em; text-transform: uppercase; } .reveal .env-file-flow code { font-size: 0.95em; white-space: nowrap; } .reveal .env-handoff { display: grid; grid-template-columns: 1fr 4.2rem 1fr; gap: 0.6rem; align-items: center; margin-top: 0.95rem; } .reveal .env-machine { display: grid; gap: 0.52rem; padding: 0.82rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); box-shadow: 0 12px 26px rgba(15,23,42,0.07); } .reveal .env-machine h3 { margin: 0; font-size: 0.72em; } .reveal .env-machine pre { margin: 0; } .reveal .env-handoff-arrow { display: grid; place-items: center; width: 4.2rem; height: 4.2rem; border-radius: 8px; border: 1px solid rgba(5,150,105,0.22); background: rgba(5,150,105,0.08); color: rgb(5,150,105); font-size: 1.25em; font-weight: 900; } .reveal .env-native-board { display: grid; grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr); gap: 0.82rem; align-items: stretch; margin-top: 0.92rem; } .reveal .env-native-board .env-grid { margin-top: 0; } .reveal .env-native-stack { display: grid; align-content: stretch; gap: 0.5rem; padding: 0.76rem; border: 1px solid rgba(5,150,105,0.18); border-radius: 8px; background: linear-gradient(135deg, rgba(5,150,105,0.10), rgba(255,255,255,0.80)); } .reveal .env-native-stack span { display: grid; place-items: center; min-height: 3.5rem; border: 1px solid rgba(15,23,42,0.11); border-radius: 8px; background: rgba(255,255,255,0.82); color: var(--env-slate); font-size: 0.56em; font-weight: 850; text-align: center; } .reveal .env-native-stack span:nth-child(1) { border-color: rgba(2,132,199,0.25); } .reveal .env-native-stack span:nth-child(2) { border-color: rgba(5,150,105,0.28); } .reveal .env-native-stack span:nth-child(3) { border-color: rgba(194,65,12,0.24); } .reveal .env-native-stack span:nth-child(4) { border-color: rgba(126,34,147,0.24); } .reveal .env-spec-board { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: 0.82rem; align-items: stretch; margin-top: 0.9rem; } .reveal .env-spec-pipeline { display: grid; gap: 0.5rem; } .reveal .env-spec-step { display: grid; grid-template-columns: 3.1rem minmax(0, 1fr); gap: 0.56rem; align-items: center; min-height: 4.45rem; padding: 0.58rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-spec-step span { display: grid; place-items: center; width: 2.7rem; height: 2.7rem; border-radius: 8px; background: rgb(5,150,105); color: white; font-size: 0.48em; font-weight: 900; } .reveal .env-spec-step strong { display: block; color: var(--env-slate); font-size: 0.55em; } .reveal .env-spec-step code, .reveal .env-spec-step small { display: block; margin-top: 0.14rem; color: var(--env-muted); font-size: 0.42em; white-space: normal; overflow-wrap: anywhere; } .reveal .env-uv-board { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: 0.82rem; align-items: stretch; margin-top: 0.9rem; } .reveal .env-uv-cycle { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.52rem; padding: 0.76rem; border: 1px solid rgba(126,34,147,0.18); border-radius: 8px; background: linear-gradient(135deg, rgba(166,44,180,0.10), rgba(255,255,255,0.82)); } .reveal .env-uv-cycle span { display: grid; place-items: center; min-height: 5.2rem; padding: 0.46rem; border: 1px solid rgba(126,34,147,0.16); border-radius: 8px; background: rgba(255,255,255,0.82); color: var(--env-slate); font-size: 0.52em; font-weight: 850; line-height: 1.18; text-align: center; } .reveal .env-tool-matrix { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.5rem; margin-top: 0.86rem; } .reveal .env-tool-card { min-height: 11.2rem; padding: 0.62rem; border: 1px solid rgba(15,23,42,0.12); border-top: 4px solid rgba(15,23,42,0.34); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-tool-card h3 { margin: 0 0 0.46rem 0; font-size: 0.62em; } .reveal .env-tool-card p { margin: 0; color: var(--env-muted); font-size: 0.47em; line-height: 1.26; } .reveal .env-tool-card.blue { border-top-color: rgb(2,132,199); } .reveal .env-tool-card.green { border-top-color: rgb(5,150,105); } .reveal .env-tool-card.purple { border-top-color: rgb(126,34,147); } .reveal .env-tool-card.orange { border-top-color: rgb(194,65,12); } .reveal .env-choice-map { display: grid; grid-template-columns: 13rem repeat(3, minmax(0, 1fr)); gap: 0.5rem; align-items: stretch; margin-top: 0.9rem; } .reveal .env-choice-prompt, .reveal .env-choice-option { min-height: 6.4rem; padding: 0.62rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-choice-prompt { display: grid; place-items: center; background: rgba(15,23,42,0.92); color: white; font-size: 0.58em; font-weight: 900; line-height: 1.16; text-align: center; } .reveal .env-choice-option strong { display: block; color: var(--env-slate); font-size: 0.56em; line-height: 1.14; } .reveal .env-choice-option span { display: block; margin-top: 0.35rem; color: var(--env-muted); font-size: 0.46em; line-height: 1.25; } .reveal .env-choice-option code { font-size: 0.9em; } .reveal .env-mystery { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.82rem; margin-top: 0.9rem; } .reveal .env-mystery-panel { padding: 0.78rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); box-shadow: 0 12px 26px rgba(15,23,42,0.07); } .reveal .env-mystery-panel.bad { border-top: 5px solid var(--env-orange); } .reveal .env-mystery-panel.good { border-top: 5px solid var(--env-green); } .reveal .env-project-board { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); gap: 0.82rem; margin-top: 0.9rem; } .reveal .env-tree { margin: 0; min-height: 24rem; padding: 0.76rem 0.84rem; border: 1px solid rgba(15,23,42,0.16); border-radius: 8px; background: rgba(15,23,42,0.92); color: rgb(226,232,240); font-size: 0.48em; line-height: 1.34; } .reveal .env-project-notes { display: grid; gap: 0.5rem; } .reveal .env-project-note { padding: 0.66rem 0.72rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); } .reveal .env-project-note strong { display: block; color: var(--env-slate); font-size: 0.58em; } .reveal .env-project-note span { display: block; margin-top: 0.22rem; color: var(--env-muted); font-size: 0.46em; line-height: 1.22; } .reveal .env-project-note pre { margin-top: 0.46rem; } .reveal .env-span-all { grid-column: 1 / -1; } .reveal .env-lab-board { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.62rem; margin-top: 0.9rem; } .reveal .env-lab-card { min-height: 23.8rem; padding: 0.72rem; border: 1px solid rgba(15,23,42,0.12); border-radius: 8px; background: rgba(255,255,255,0.80); box-shadow: 0 12px 26px rgba(15,23,42,0.07); } .reveal .env-lab-card h3 { margin: 0 0 0.5rem 0; font-size: 0.66em; } .reveal .env-lab-card pre { margin: 0; } .reveal .env-close { display: grid; grid-template-columns: minmax(0, 1fr) 21rem; gap: 1.4rem; align-items: center; margin-top: 1.1rem; } .reveal .env-close h3 { margin: 0; color: var(--env-slate); font-size: 1.15em; line-height: 1.06; } .reveal .env-close p { margin: 0.72rem 0 0 0; color: var(--env-muted); font-size: 0.7em; line-height: 1.3; } .reveal .env-qr-panel { display: grid; place-items: center; padding: 0.82rem; border: 1px solid rgba(15,23,42,0.13); border-radius: 8px; background: rgba(255,255,255,0.82); box-shadow: 0 14px 30px rgba(15,23,42,0.08); } .reveal .env-qr-panel img { width: 100%; max-width: 18rem; height: auto; } .reveal .env-atlas { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.62rem; min-height: 28.6rem; margin-top: 0.5rem; overflow: hidden; border: 1px solid rgba(15,23,42,0.16); border-radius: 8px; background: linear-gradient(90deg, rgba(15,23,42,0.05) 1px, transparent 1px), linear-gradient(0deg, rgba(15,23,42,0.04) 1px, transparent 1px), linear-gradient(135deg, rgba(255,255,255,0.90), rgba(240,249,255,0.76) 45%, rgba(240,253,244,0.74)); background-size: 28px 28px, 28px 28px, auto; box-shadow: 0 18px 38px rgba(15,23,42,0.10); } .reveal .env-atlas-board { display: grid; grid-template-rows: auto repeat(4, minmax(4.85rem, 1fr)); gap: 0.62rem; padding: 0.82rem; } .reveal .env-atlas-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.7rem; align-items: center; padding: 0.66rem 0.82rem; border: 1px solid rgba(15,23,42,0.10); border-radius: 8px; background: rgba(255,255,255,0.78); } .reveal .env-atlas-top strong { display: block; color: var(--env-slate); font-size: 0.72em; line-height: 1.16; } .reveal .env-atlas-top span { display: block; margin-top: 0.18rem; color: var(--env-muted); font-size: 0.48em; line-height: 1.24; } .reveal .env-pathway { --path-ink: var(--env-blue); --path-rgb: 2,132,199; display: grid; grid-template-columns: 9.4rem repeat(3, minmax(0, 1fr)); gap: 0.54rem; align-items: stretch; } .reveal .env-pathway.green { --path-ink: var(--env-green); --path-rgb: 5,150,105; } .reveal .env-pathway.orange { --path-ink: var(--env-orange); --path-rgb: 194,65,12; } .reveal .env-pathway.slate { --path-ink: var(--env-slate); --path-rgb: 15,23,42; } .reveal .env-path-label, .reveal .env-atlas-link { border: 1px solid rgba(15,23,42,0.11); border-radius: 8px; background: rgba(255,255,255,0.82); } .reveal .env-path-label { display: grid; align-content: center; padding: 0.58rem 0.62rem; border-left: 5px solid var(--path-ink); } .reveal .env-path-label span { color: rgba(var(--path-rgb),0.64); font-size: 0.52em; font-weight: 900; line-height: 1; } .reveal .env-path-label strong { margin-top: 0.22rem; color: var(--env-slate); font-size: 0.66em; line-height: 1.1; } .reveal .env-path-label em { margin-top: 0.2rem; color: var(--env-muted); font-size: 0.42em; font-style: normal; line-height: 1.2; } .reveal .env-atlas-link { display: grid; align-content: start; min-height: 4.95rem; padding: 0.62rem 0.66rem; color: inherit; text-decoration: none; box-shadow: 0 8px 20px rgba(15,23,42,0.05); } .reveal .env-atlas-link::before { content: ""; display: block; width: 2.35rem; height: 0.26rem; margin-bottom: 0.4rem; border-radius: 999px; background: var(--path-ink); } .reveal .env-atlas-link strong { color: var(--env-slate); font-size: 0.54em; line-height: 1.16; } .reveal .env-atlas-link span { display: block; margin-top: 0.2rem; color: var(--env-muted); font-size: 0.4em; line-height: 1.22; overflow-wrap: anywhere; } .reveal .slides section .env-tool-pill img, .reveal .slides section .env-logo-strip img, .reveal .slides section .env-cheat-logo, .reveal .slides section .env-ref-logo img, .reveal .slides section .env-qr-panel img { margin: 0; box-shadow: none; object-fit: contain; } .reveal .slides section .env-tool-pill img { width: 1.05rem; height: 1.05rem; border-radius: 0; background: transparent; } .reveal .slides section .env-logo-strip img { width: auto; height: 2.55rem; max-width: 9.5rem; padding: 0.16rem 0.22rem; border-radius: 6px; background: rgba(255,255,255,0.68); } .reveal .slides section .env-cheat-logo { width: 3.45rem; height: 3.45rem; } .reveal .slides section .env-ref-logo img { width: auto; height: auto; max-width: 1.58rem; max-height: 1.58rem; border-radius: 0; } .reveal .slides section .env-qr-panel img { width: 100%; max-width: 18rem; height: auto; } @media (max-width: 1100px) { .reveal .env-grid.two, .reveal .env-grid.three, .reveal .env-grid.four, .reveal .env-flow, .reveal .env-command-bank, .reveal .env-cheat-footer, .reveal .env-cheat, .reveal .env-debug-board, .reveal .env-debug-steps, .reveal .env-debug-bottom, .reveal .env-study-layout, .reveal .env-cover-shell, .reveal .env-roadmap, .reveal .env-compare, .reveal .env-formula, .reveal .env-stack-layout, .reveal .env-workflow-board, .reveal .env-step-board, .reveal .env-handoff, .reveal .env-native-board, .reveal .env-spec-board, .reveal .env-uv-board, .reveal .env-tool-matrix, .reveal .env-choice-map, .reveal .env-mystery, .reveal .env-project-board, .reveal .env-lab-board, .reveal .env-close, .reveal .env-atlas, .reveal .env-atlas-top, .reveal .env-pathway, .reveal .env-ref-grid, .reveal .env-scipe-links { grid-template-columns: 1fr; } .reveal .env-cover-map { min-height: 17rem; } .reveal .env-lane { grid-template-columns: 1fr; } .reveal .env-handoff-arrow { width: 100%; } .reveal .env-cheat { min-height: auto; } .reveal .env-cheat-rail { border-right: 0; border-bottom: 1px solid rgba(15,23,42,0.12); } .reveal .env-cheat-files { grid-template-columns: repeat(2, minmax(0, 1fr)); } .reveal .env-debug-rail { border-right: 0; border-bottom: 1px solid rgba(194,65,12,0.18); } .reveal .env-logo-row img { height: 54px; } } </style> ## Learning goals <p class="env-section-note">The arc of the session: isolate a project, make the moving parts visible, write the state down, then choose a workflow that teammates can rebuild.</p> <div class="env-roadmap"> <div class="env-road-step blue" data-step="01"> <h3>Stop dependency drift</h3> <p>Make today's notebook or script runnable tomorrow, on another machine, by another person.</p> </div> <div class="env-road-step green" data-step="02"> <h3>Name the pieces</h3> <p>Interpreter, packages, command-line tools, project files, and lock/spec files.</p> </div> <div class="env-road-step orange" data-step="03"> <h3>Use core workflows</h3> <p>Create, activate, install, record, reproduce, and debug environments.</p> </div> <div class="env-road-step purple" data-step="04"> <h3>Pick the right tool</h3> <p>Use <code>pip</code>, <code>conda</code>/<code>micromamba</code>, <code>uv</code>, <code>pipx</code>, and containers for the right job.</p> </div> </div> <div class="env-callout green"> Rule of thumb: one project gets one environment and one committed environment specification. </div> --- ## Why environments exist <div class="env-compare"> <div class="env-world bad"> <h3>Without an environment</h3> <div class="env-collision" aria-label="Two projects colliding in one global Python install"> <span>Project A<br /><code>numpy 2.x</code></span> <span>Project B<br /><code>numpy 1.x</code></span> <span>global site-packages</span> <span>one mutable Python</span> </div> <ul> <li>Project A upgrades <code>numpy</code>; Project B breaks.</li> <li>A notebook uses your system Python by accident.</li> <li>A package works on your laptop but not on the cluster.</li> <li>"It worked yesterday" has no audit trail.</li> </ul> </div> <div class="env-world good"> <h3>With an environment</h3> <div class="env-islands" aria-label="Separate environments per project"> <span>Project A<br /><code>.venv/</code></span> <span>Project B<br /><code>conda env</code></span> <span>Notebook<br />kernel</span> <span>shared<br />spec file</span> </div> <ul> <li>Dependencies are isolated per project.</li> <li>The Python executable is predictable.</li> <li>Installed packages can be listed and recreated.</li> <li>Teammates can start from the same spec.</li> </ul> </div> </div> <div class="env-formula" aria-label="Environment formula"> <span>Python</span> <span>packages</span> <span>commands</span> <span>paths</span> </div> --- ## Abstraction layers of an environment <div class="env-stack-layout"> <div class="env-stack" aria-label="Four layers of a Python environment"> <div class="env-stack-layer"> <div class="env-stack-num">1</div> <div><h3>Python</h3><p>The interpreter, for example <code>3.12</code> or <code>3.13</code>.</p></div> </div> <div class="env-stack-layer"> <div class="env-stack-num">2</div> <div><h3>Environment</h3><p>A directory containing its own Python executable and installed packages.</p></div> </div> <div class="env-stack-layer"> <div class="env-stack-num">3</div> <div><h3>Package manager</h3><p>The tool that resolves, downloads, and installs dependencies.</p></div> </div> <div class="env-stack-layer"> <div class="env-stack-num">4</div> <div><h3>Spec or lock</h3><p>The file that tells someone else how to rebuild the environment.</p></div> </div> </div> <div class="env-lane-board"> <div class="env-lane"> <strong>pip / PyPI</strong> <span><code>numpy</code><code>requests</code><code>transformers</code></span> <code>requirements.txt<br />pyproject.toml</code> </div> <div class="env-lane"> <strong>conda channels</strong> <span><code>python</code><code>scipy</code><em>native libraries</em><em>GPU stacks</em></span> <code>environment.yml<br />conda-lock.yml</code> </div> <div class="env-lane"> <strong>uv projects</strong> <span><em>project deps</em><em>scripts</em><em>tools</em><em>Python versions</em></span> <code>pyproject.toml<br />uv.lock</code> </div> </div> </div> <div class="env-callout"> Intent files say what you asked for; lock or freeze files say what was actually resolved. </div> --- ## Minimum workflow: venv + pip <div class="env-workflow-board"> <div class="env-step-board"> <div class="env-work-step"> <span><strong>01. Create</strong><em>project-local environment</em></span> <code>python -m venv .venv</code> </div> <div class="env-work-step"> <span><strong>02. Activate</strong><em>point the shell at it</em></span> <code>source .venv/bin/activate</code> </div> <div class="env-work-step"> <span><strong>03. Install</strong><em>upgrade pip, then packages</em></span> <code>python -m pip install -U pip python -m pip install numpy pandas matplotlib</code> </div> <div class="env-work-step"> <span><strong>04. Record</strong><em>write the resolved state</em></span> <code>python -m pip freeze > requirements.txt</code> </div> </div> <div class="env-work-panel"> <h3>Use this for</h3> <div class="env-use-list"> <span>small projects</span> <span>teaching examples</span> <span>pure Python dependencies</span> <span>packages with PyPI wheels</span> </div> <div class="env-file-flow"> <span><b>commit</b><span>project code</span></span> <span><b>ignore</b><span><code>.venv/</code> local only</span></span> <span><b>commit</b><span><code>requirements.txt</code> environment spec</span></span> </div> <p>Simple reproducibility comes from separating the environment directory from the file that describes it.</p> </div> </div> <div class="env-callout"> Prefer <code>python -m pip</code>: it installs into the environment used by that exact <code>python</code>. </div> --- ## Recreate a pip environment <div class="env-handoff"> <div class="env-machine"> <h3>Original machine</h3> <pre class="env-pre"><code>python -m venv .venv source .venv/bin/activate python -m pip install numpy pandas python -m pip freeze > requirements.txt</code></pre> <ul class="env-small-list"> <li>Commit the source code.</li> <li>Commit <code>requirements.txt</code>.</li> <li>Do not commit <code>.venv/</code>.</li> </ul> </div> <div class="env-handoff-arrow" aria-hidden="true">→</div> <div class="env-machine"> <h3>Another machine</h3> <pre class="env-pre"><code>git clone PROJECT cd PROJECT python -m venv .venv source .venv/bin/activate python -m pip install -r requirements.txt python train.py</code></pre> </div> </div> <div class="env-grid two"> <div class="env-card"> <h3>Check what you are using</h3> <pre class="env-pre"><code>which python python -m pip --version python -c "import sys; print(sys.executable)" python -c "import numpy; print(numpy.__version__)"</code></pre> </div> <div class="env-card"> <h3>Expected evidence</h3> <ul> <li><code>which python</code> points inside <code>.venv/</code>.</li> <li><code>python -m pip --version</code> reports that same environment.</li> <li>The package import succeeds from the environment path.</li> </ul> </div> </div> <div class="env-callout orange"> Do not install project libraries into the OS Python. If the system blocks you, create an environment instead of forcing the install. </div> --- ## Conda and micromamba <div class="env-native-board"> <div class="env-native-stack" aria-label="Conda environment stack"> <span>Python interpreter</span> <span>Python packages</span> <span>compiled libraries</span> <span>CUDA / platform stack</span> </div> <div class="env-grid two"> <div class="env-card"> <h3>What they solve</h3> <ul> <li>Python plus non-Python binary dependencies</li> <li>Scientific stacks with compiled libraries</li> <li>GPU/CUDA-sensitive projects</li> <li>Cross-language packages from channels</li> </ul> </div> <div class="env-card"> <h3>Why micromamba?</h3> <ul> <li>Small standalone executable</li> <li>No default <code>base</code> Python environment</li> <li>Fast conda-compatible environment creation</li> <li>Useful on servers and CI</li> </ul> </div> <div class="env-card env-span-all"> <pre class="env-pre"><code>micromamba create -n ml -c conda-forge python=3.12 numpy scipy jupyterlab micromamba activate ml python -c "import scipy; print(scipy.__version__)"</code></pre> </div> </div> </div> --- ## Conda specs: environment.yml <div class="env-spec-board"> <div class="env-card"> <h3>Human-readable spec</h3> <pre class="env-pre"><code>name: ml channels: - conda-forge dependencies: - python=3.12 - numpy - scipy - jupyterlab - pip - pip: - transformers</code></pre> </div> <div class="env-spec-pipeline"> <div class="env-spec-step"> <span>1</span> <div><strong>Write intent</strong><code>environment.yml</code><small>human-readable package choices and channels</small></div> </div> <div class="env-spec-step"> <span>2</span> <div><strong>Create or recreate</strong><code>conda env create -f environment.yml<br />micromamba create -f environment.yml</code></div> </div> <div class="env-spec-step"> <span>3</span> <div><strong>Lock when needed</strong><code>conda-lock.yml</code><small>stricter solves for teammates, CI, and deployment</small></div> </div> </div> </div> <div class="env-callout orange"> If you must mix conda and pip, install conda packages first, then pip packages. Record both in <code>environment.yml</code>. </div> --- ## uv: the modern fast path <div class="env-uv-board"> <div class="env-uv-cycle" aria-label="uv project cycle"> <span><code>uv init</code><br />create project</span> <span><code>uv add</code><br />declare dependencies</span> <span><code>uv run</code><br />execute in environment</span> <span><code>uv sync --locked</code><br />reproduce the solve</span> </div> <div class="env-card"> <h3>Project workflow</h3> <pre class="env-pre"><code>uv init myproj cd myproj uv add numpy pandas scikit-learn uv run python train.py uv lock uv sync --locked</code></pre> <ul> <li>Project setup with <code>pyproject.toml</code></li> <li>Project-local <code>.venv</code> management</li> <li>Locking with <code>uv.lock</code></li> <li>Running scripts and command-line tools</li> </ul> </div> </div> <div class="env-callout green"> Good default for new Python-only projects. It is not a replacement for conda packages or system-level CUDA libraries. </div> --- ## uv can also speak pip <div class="env-grid two"> <div class="env-card"> <h3>Use with existing projects</h3> <pre class="env-pre"><code>uv venv source .venv/bin/activate uv pip install -r requirements.txt uv pip freeze > requirements.txt</code></pre> </div> <div class="env-card"> <h3>Run tools without polluting projects</h3> <pre class="env-pre"><code>uvx ruff check . uvx pyright uv tool install ruff ruff check .</code></pre> </div> </div> <div class="env-callout"> <code>uvx</code> is the short form for running a tool in an isolated environment. </div> --- ## Other useful tools <div class="env-tool-matrix"> <div class="env-tool-card blue"> <h3><code>pipx</code></h3> <p>Use for global Python command-line apps in isolated environments. Do not use for project dependencies.</p> </div> <div class="env-tool-card green"> <h3><code>ipykernel</code></h3> <p>Use when a notebook must point at this exact environment. It is not the package manager.</p> </div> <div class="env-tool-card purple"> <h3><code>pyenv</code> / <code>mise</code></h3> <p>Use to switch interpreter versions on one machine. It does not lock package dependencies.</p> </div> <div class="env-tool-card orange"> <h3><code>conda-lock</code></h3> <p>Use for exact conda solves across platforms or CI. It is not a package installer by itself.</p> </div> <div class="env-tool-card"> <h3>Docker / Apptainer</h3> <p>Use for OS-level reproducibility, deployment, or HPC portability. It is not the quickest local package manager.</p> </div> </div> <div class="env-callout green"> The best tool is the one your team can recreate from clean checkout instructions. </div> --- ## Which tool should I choose? <div class="env-choice-map" aria-label="Tool choice map"> <div class="env-choice-prompt">What kind of problem is this?</div> <div class="env-choice-option"> <strong>Learning Python or existing requirements?</strong> <span>Start with <code>venv + pip</code>, or use <code>uv pip</code> when speed matters.</span> </div> <div class="env-choice-option"> <strong>New Python-only project?</strong> <span>Use <code>uv</code> with <code>pyproject.toml</code>, <code>.venv/</code>, and <code>uv.lock</code>.</span> </div> <div class="env-choice-option"> <strong>Scientific, compiled, or GPU stack?</strong> <span>Use <code>conda</code> or <code>micromamba</code>, usually with <code>conda-forge</code>.</span> </div> <div class="env-choice-prompt">How strict must reproduction be?</div> <div class="env-choice-option"> <strong>Single machine</strong> <span>Record versions and commands. Keep setup instructions short enough to follow.</span> </div> <div class="env-choice-option"> <strong>Team or CI</strong> <span>Commit <code>requirements.txt</code>, <code>uv.lock</code>, or <code>environment.yml</code>.</span> </div> <div class="env-choice-option"> <strong>Deployment or cluster</strong> <span>Consider <code>conda-lock</code>, Docker, or Apptainer when OS details matter.</span> </div> </div> <div class="env-callout"> Simple is good. Reproducible is better. Debuggable is non-negotiable. </div> --- ## Do not create mystery environments <div class="env-mystery"> <div class="env-mystery-panel bad"> <h3>Avoid</h3> <ul> <li>Installing everything globally</li> <li>Changing package versions without recording them</li> <li>Using <code>pip</code> from one Python and running another</li> <li>Mixing conda and pip without documenting the boundary</li> <li>Ignoring the first real install error</li> </ul> </div> <div class="env-mystery-panel good"> <h3>Prefer</h3> <ul> <li>Commit <code>requirements.txt</code>, <code>pyproject.toml</code> + <code>uv.lock</code>, or <code>environment.yml</code></li> <li>Ignore <code>.venv/</code> and conda environment directories</li> <li>Use <code>python -m pip</code> when using pip</li> <li>Recreate the environment when dependency state gets confusing</li> <li>Paste the full error into the issue or lab notes</li> </ul> </div> </div> --- ## A practical ML project layout <div class="env-project-board"> <pre class="env-tree"><code>project/ README.md src/ notebooks/ scripts/ tests/ spec: requirements.txt or environment.yml or pyproject.toml + uv.lock ignore: .venv/ __pycache__/ .ipynb_checkpoints/ data/raw/ outputs/ *.egg-info/</code></pre> <div class="env-project-notes"> <div class="env-project-note"> <strong>Commit one route</strong> <span>Choose <code>requirements.txt</code>, <code>environment.yml</code>, or <code>pyproject.toml + uv.lock</code>; make it clear in the README.</span> </div> <div class="env-project-note"> <strong>Files to ignore</strong> <span><code>.venv/</code>, caches, notebook checkpoints, raw data, outputs, and build artifacts should stay out of git.</span> </div> <div class="env-project-note"> <strong>Notebook kernel</strong> <pre class="env-pre"><code>python -m pip install ipykernel python -m ipykernel install --user \ --name PROJECT \ --display-name "Python (PROJECT)"</code></pre> <span>Activate the environment first, then register the kernel.</span> </div> </div> </div> <div class="env-callout green"> Data and model artifacts need their own plan. Environment files reproduce software, not the contents of your hard drive. </div> --- ## Debug checklist <div class="env-debug-board"> <aside class="env-debug-rail"> <div class="env-debug-badge">DBG</div> <h3>Find the layer first</h3> <p>Do not reinstall randomly. Prove which interpreter, package copy, and environment spec are actually being used.</p> <div class="env-debug-chipset"> <div class="env-debug-chip">Interpreter</div> <div class="env-debug-chip">Package path</div> <div class="env-debug-chip">Fresh solve</div> </div> </aside> <div class="env-debug-main"> <div class="env-debug-steps"> <div class="env-debug-card"> <div class="env-debug-num">01</div> <h3>Confirm Python</h3> <div class="env-debug-terminal"> <code>which python</code> <code>python --version</code> <code>python -c "import sys; print(sys.executable)"</code> </div> <p><strong>Expected:</strong> the path points at <code>.venv</code>, conda env, or uv project env.</p> </div> <div class="env-debug-card"> <div class="env-debug-num">02</div> <h3>Confirm package source</h3> <div class="env-debug-terminal"> <code>python -m pip show PACKAGE</code> <code>python -m pip check</code> <code>python -c "import PACKAGE; print(PACKAGE.__file__)"</code> </div> <p><strong>Expected:</strong> the imported package lives inside the active environment, not a global site-packages path.</p> </div> <div class="env-debug-card"> <div class="env-debug-num">03</div> <h3>Recreate cleanly</h3> <div class="env-debug-terminal"> <code>rm -rf .venv</code> <code>uv sync</code> <code>python -m pip install -r requirements.txt</code> <code>conda env create -f environment.yml</code> </div> <p><strong>Expected:</strong> a clean environment either builds successfully or fails with the real dependency error.</p> </div> </div> <div class="env-debug-bottom"> <div class="env-debug-callout"> If a build fails, classify the first real error before changing packages. </div> <div class="env-debug-axis"> <span>Python version</span> <span>Package version</span> <span>Compiled library</span> <span>Network / index</span> <span>Platform</span> <span>Env spec</span> </div> </div> </div> </div> --- ## Mini lab <div class="env-lab-board"> <div class="env-lab-card"> <h3>Task A: pip route</h3> <pre class="env-pre"><code>mkdir env-lab && cd env-lab python -m venv .venv source .venv/bin/activate python -m pip install pandas python -c "import pandas; print(pandas.__version__)" python -m pip freeze > requirements.txt</code></pre> </div> <div class="env-lab-card"> <h3>Task B: conda route</h3> <pre class="env-pre"><code>conda create -n env-lab \ -c conda-forge python=3.12 pandas conda activate env-lab python -c "import pandas; print(pandas.__version__)" conda env export --from-history > environment.yml</code></pre> </div> <div class="env-lab-card"> <h3>Task C: uv route</h3> <pre class="env-pre"><code>uv init env-lab-uv cd env-lab-uv uv add pandas uv run python -c "import pandas; print(pandas.__version__)" uv sync --locked</code></pre> </div> </div> <div class="env-callout"> Compare: Which files appeared? Which command proves the package is installed in the intended environment? </div> --- ## Cheat sheet: pip <div class="env-cheat pip"> <aside class="env-cheat-rail"> <img class="env-cheat-logo" src="/assets/slides/2026-05-21-python-env/pip-icon.svg" alt="" aria-hidden="true" /> <div class="env-cheat-kicker">PyPI + venv</div> <h3>pip</h3> <p>The lightweight route for teaching, notebooks, and projects whose dependencies are available from PyPI.</p> <div class="env-cheat-files"> <div class="env-file-pair"><span>Commit</span><code>requirements.txt</code></div> <div class="env-file-pair"><span>Ignore</span><code>.venv/</code></div> </div> </aside> <div class="env-cheat-main"> <div class="env-flow"> <div class="env-flow-card"> <div class="env-step">01</div> <strong>Create and enter</strong> <code>python -m venv .venv source .venv/bin/activate</code> </div> <div class="env-flow-card"> <div class="env-step">02</div> <strong>Install packages</strong> <code>python -m pip install -U pip python -m pip install numpy pandas</code> </div> <div class="env-flow-card"> <div class="env-step">03</div> <strong>Record exact state</strong> <code>python -m pip freeze > requirements.txt</code> </div> <div class="env-flow-card"> <div class="env-step">04</div> <strong>Rebuild elsewhere</strong> <code>python -m pip install -r requirements.txt</code> </div> </div> <div class="env-command-bank"> <pre class="env-terminal"><code># first checks when something feels wrong which python python -m pip --version python -m pip check python -c "import sys; print(sys.executable)"</code></pre> <div class="env-dos"> <div class="env-do"><strong>Rule</strong><span>Use <code>python -m pip</code> so the installer belongs to the Python you will run.</span></div> <div class="env-do"><strong>Editable</strong><span>For your own package, use <code>python -m pip install -e .</code>.</span></div> <div class="env-do"><strong>Reset</strong><span>If dependency state gets strange, delete <code>.venv/</code> and rebuild from the file.</span></div> </div> </div> <div class="env-cheat-footer"> <div class="env-rule"><strong>Python</strong><code>python --version</code></div> <div class="env-rule"><strong>Pip version</strong><code>python -m pip --version</code></div> <div class="env-rule"><strong>List</strong><code>python -m pip list</code></div> <div class="env-rule"><strong>Inspect</strong><code>python -m pip show PACKAGE</code></div> <div class="env-rule"><strong>Check deps</strong><code>python -m pip check</code></div> <div class="env-rule"><strong>Upgrade</strong><code>python -m pip install -U PACKAGE</code></div> <div class="env-rule"><strong>Uninstall</strong><code>python -m pip uninstall PACKAGE</code></div> <div class="env-rule"><strong>Editable</strong><code>python -m pip install -e .</code></div> <div class="env-rule"><strong>Extras</strong><code>python -m pip install ".[dev]"</code></div> <div class="env-rule"><strong>Freeze</strong><code>python -m pip freeze > requirements.txt</code></div> <div class="env-rule"><strong>Install file</strong><code>python -m pip install -r requirements.txt</code></div> <div class="env-rule"><strong>Clear cache</strong><code>python -m pip cache purge</code></div> </div> </div> </div> --- ## Cheat sheet: conda <div class="env-cheat conda"> <aside class="env-cheat-rail"> <img class="env-cheat-logo" src="/assets/slides/2026-05-21-python-env/conda-icon.svg" alt="" aria-hidden="true" /> <div class="env-cheat-kicker">Channels + binaries</div> <h3>conda</h3> <p>The practical route when Python packages need compiled libraries, system libraries, CUDA stacks, or cluster-friendly specs.</p> <div class="env-cheat-files"> <div class="env-file-pair"><span>Commit</span><code>environment.yml</code></div> <div class="env-file-pair"><span>Channel</span><code>conda-forge</code></div> </div> </aside> <div class="env-cheat-main"> <div class="env-flow"> <div class="env-flow-card"> <div class="env-step">01</div> <strong>Create named env</strong> <code>conda create -n ml -c conda-forge python=3.12 numpy scipy</code> </div> <div class="env-flow-card"> <div class="env-step">02</div> <strong>Activate it</strong> <code>conda activate ml</code> </div> <div class="env-flow-card"> <div class="env-step">03</div> <strong>Add dependencies</strong> <code>conda install -n ml -c conda-forge jupyterlab</code> </div> <div class="env-flow-card"> <div class="env-step">04</div> <strong>Recreate from spec</strong> <code>conda env create -f environment.yml</code> </div> </div> <div class="env-command-bank"> <pre class="env-terminal"><code>name: ml channels: - conda-forge dependencies: - python=3.12 - numpy - scipy - pip - pip: - transformers</code></pre> <div class="env-dos"> <div class="env-do"><strong>Channels</strong><span>Prefer one channel family per environment and write the channels into the spec.</span></div> <div class="env-do"><strong>Mixing</strong><span>Install conda packages first; reserve the <code>pip:</code> section for PyPI-only packages.</span></div> <div class="env-do"><strong>Servers</strong><span>The same <code>environment.yml</code> can be created with <code>micromamba create -f environment.yml</code>.</span></div> </div> </div> <div class="env-cheat-footer"> <div class="env-rule"><strong>Envs</strong><code>conda info --envs</code></div> <div class="env-rule"><strong>Packages</strong><code>conda list -n ml</code></div> <div class="env-rule"><strong>Search</strong><code>conda search -c conda-forge PACKAGE</code></div> <div class="env-rule"><strong>Install</strong><code>conda install -n ml PACKAGE</code></div> <div class="env-rule"><strong>Update</strong><code>conda update -n ml PACKAGE</code></div> <div class="env-rule"><strong>Remove pkg</strong><code>conda remove -n ml PACKAGE</code></div> <div class="env-rule"><strong>Minimal export</strong><code>conda env export --from-history > environment.yml</code></div> <div class="env-rule"><strong>Exact export</strong><code>conda env export -n ml > environment-full.yml</code></div> <div class="env-rule"><strong>Delete env</strong><code>conda env remove -n ml</code></div> <div class="env-rule"><strong>Run in env</strong><code>conda run -n ml python train.py</code></div> <div class="env-rule"><strong>Clone env</strong><code>conda create -n ml-copy --clone ml</code></div> <div class="env-rule"><strong>Clean cache</strong><code>conda clean --all</code></div> </div> </div> </div> --- ## Cheat sheet: uv <div class="env-cheat uv"> <aside class="env-cheat-rail"> <img class="env-cheat-logo" src="/assets/slides/2026-05-21-python-env/uv-icon.svg" alt="" aria-hidden="true" /> <div class="env-cheat-kicker">Project + lock</div> <h3>uv</h3> <p>The fast default for new Python projects: it manages the project environment, dependency resolution, and lockfile.</p> <div class="env-cheat-files"> <div class="env-file-pair"><span>Commit</span><code>pyproject.toml</code></div> <div class="env-file-pair"><span>Lock</span><code>uv.lock</code></div> <div class="env-file-pair"><span>Ignore</span><code>.venv/</code></div> </div> </aside> <div class="env-cheat-main"> <div class="env-flow"> <div class="env-flow-card"> <div class="env-step">01</div> <strong>Start project</strong> <code>uv init myproj cd myproj</code> </div> <div class="env-flow-card"> <div class="env-step">02</div> <strong>Add dependencies</strong> <code>uv add numpy pandas scikit-learn</code> </div> <div class="env-flow-card"> <div class="env-step">03</div> <strong>Run in env</strong> <code>uv run python train.py</code> </div> <div class="env-flow-card"> <div class="env-step">04</div> <strong>Reproduce exactly</strong> <code>uv sync --locked</code> </div> </div> <div class="env-command-bank"> <pre class="env-terminal"><code># project mental model pyproject.toml # dependency intent uv.lock # resolved versions .venv/ # local environment # existing requirements.txt project uv venv uv pip install -r requirements.txt</code></pre> <div class="env-dos"> <div class="env-do"><strong>Run</strong><span>Use <code>uv run ...</code> so commands execute inside the project environment.</span></div> <div class="env-do"><strong>Lock</strong><span>Commit <code>uv.lock</code> when teammates, CI, or deployment need the same solve.</span></div> <div class="env-do"><strong>Boundary</strong><span>Use conda or containers when the problem is system libraries rather than Python packages.</span></div> </div> </div> <div class="env-cheat-footer"> <div class="env-rule"><strong>Add package</strong><code>uv add PACKAGE</code></div> <div class="env-rule"><strong>Add dev</strong><code>uv add --dev pytest ruff</code></div> <div class="env-rule"><strong>Remove</strong><code>uv remove PACKAGE</code></div> <div class="env-rule"><strong>Run tests</strong><code>uv run pytest</code></div> <div class="env-rule"><strong>Sync lock</strong><code>uv sync --locked</code></div> <div class="env-rule"><strong>Update lock</strong><code>uv lock</code></div> <div class="env-rule"><strong>Pin Python</strong><code>uv python pin 3.12</code></div> <div class="env-rule"><strong>One-off tool</strong><code>uvx ruff check .</code></div> <div class="env-rule"><strong>Install tool</strong><code>uv tool install pyright</code></div> <div class="env-rule"><strong>Dependency tree</strong><code>uv tree</code></div> <div class="env-rule"><strong>Install Python</strong><code>uv python install 3.12</code></div> <div class="env-rule"><strong>Export reqs</strong><code>uv export --format requirements.txt > requirements.txt</code></div> </div> </div> </div> --- ## Resources <div class="env-study-layout"> <div class="env-scipe-panel"> <div class="env-scipe-head"> <div class="env-scipe-mark">SCIPE</div> <div> <h3>SCIPE LLM workshop</h3> <p>Use these materials for the hands-on LLM examples and follow-up practice.</p> </div> </div> <div class="env-scipe-links"> <a href="https://oh-scipe.github.io/llm-workshop26/"><strong>Workshop site</strong><span>Schedule, logistics, recordings, and updates</span></a> <a href="https://github.com/oh-scipe/llm-workshop26/tree/main/tutorials"><strong>Tutorial notebooks</strong><span>Hands-on notebooks for local practice</span></a> <a href="https://oh-scipe.github.io/llm-workshop26/recordings.html"><strong>Recordings</strong><span>Session-by-session video links</span></a> <a href="https://github.com/oh-scipe/llm-workshop26"><strong>GitHub repo</strong><span>Source materials and updates</span></a> </div> </div> <div class="env-ref-panel"> <h3>Environment references</h3> <div class="env-ref-grid"> <div class="env-ref-card"> <div class="env-ref-logo"><img src="/assets/slides/2026-05-21-python-env/pip-icon.svg" alt="" aria-hidden="true" /></div> <div><a href="https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/">pip + venv guide</a><span>packaging.python.org</span></div> </div> <div class="env-ref-card"> <div class="env-ref-logo"><img src="/assets/slides/2026-05-21-python-env/conda-icon.svg" alt="" aria-hidden="true" /></div> <div><a href="https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html">Conda environments</a><span>docs.conda.io</span></div> </div> <div class="env-ref-card"> <div class="env-ref-logo">M</div> <div><a href="https://mamba.readthedocs.io/en/stable/user_guide/micromamba.html">Micromamba guide</a><span>mamba.readthedocs.io</span></div> </div> <div class="env-ref-card"> <div class="env-ref-logo"><img src="/assets/slides/2026-05-21-python-env/uv-icon.svg" alt="" aria-hidden="true" /></div> <div><a href="https://docs.astral.sh/uv/">uv docs</a><span>docs.astral.sh/uv</span></div> </div> <div class="env-ref-card"> <div class="env-ref-logo">pipx</div> <div><a href="https://pipx.pypa.io/">pipx docs</a><span>pipx.pypa.io</span></div> </div> <div class="env-ref-card"> <div class="env-ref-logo">PyPA</div> <div><a href="https://packaging.python.org/en/latest/guides/tool-recommendations/">Tool recommendations</a><span>packaging.python.org</span></div> </div> </div> </div> </div> --- ## Further study <!-- .slide: data-background-gradient="linear-gradient(135deg, rgba(15,23,42,0.10) 0%, rgba(255,255,255,0.94) 46%, rgba(5,150,105,0.12) 100%)" --> <div class="env-atlas"> <div class="env-atlas-board"> <div class="env-atlas-top"> <div> <strong>Choose the path that matches the problem in front of you.</strong> <span>Install failures, project config, notebook kernels, and portable research runs each need a different next step.</span> </div> </div> <div class="env-pathway"> <div class="env-path-label"><span>01</span><strong>Install basics</strong><em>terminology and first principles</em></div> <a class="env-atlas-link" href="https://docs.python.org/3/installing/index.html"><strong>Python: Installing modules</strong><span>Official terms for pip, PyPI, venv, and install issues.</span></a> <a class="env-atlas-link" href="https://packaging.python.org/en/latest/guides/writing-pyproject-toml/"><strong>Writing pyproject.toml</strong><span>How projects declare metadata and dependencies.</span></a> <a class="env-atlas-link" href="https://realpython.com/python-virtual-environments-a-primer/"><strong>Real Python primer</strong><span>A popular explanation of virtual environments.</span></a> </div> <div class="env-pathway green"> <div class="env-path-label"><span>02</span><strong>Project managers</strong><em>when projects need structure</em></div> <a class="env-atlas-link" href="https://docs.astral.sh/uv/concepts/projects/layout/"><strong>uv project layout</strong><span>What uv writes, syncs, and locks.</span></a> <a class="env-atlas-link" href="https://python-poetry.org/docs/managing-environments/"><strong>Poetry environments</strong><span>Select, activate, inspect, and remove envs.</span></a> <a class="env-atlas-link" href="https://hatch.pypa.io/1.16/environment/"><strong>Hatch environments</strong><span>Isolated workspaces for tests and scripts.</span></a> </div> <div class="env-pathway orange"> <div class="env-path-label"><span>03</span><strong>Notebook reality</strong><em>where many ML bugs hide</em></div> <a class="env-atlas-link" href="https://code.visualstudio.com/docs/python/environments"><strong>VS Code environments</strong><span>Interpreter selection inside the editor.</span></a> <a class="env-atlas-link" href="https://ipython.readthedocs.io/en/stable/install/kernel_install.html"><strong>IPython kernels</strong><span>Expose a project env as a Jupyter kernel.</span></a> <a class="env-atlas-link" href="https://cookiecutter-data-science.drivendata.org/"><strong>Cookiecutter Data Science</strong><span>A common layout for analysis projects.</span></a> </div> <div class="env-pathway slate"> <div class="env-path-label"><span>04</span><strong>Portability</strong><em>when another machine matters</em></div> <a class="env-atlas-link" href="https://conda-forge.org/docs/user/introduction/"><strong>conda-forge intro</strong><span>Community packages and channel priority.</span></a> <a class="env-atlas-link" href="https://book.the-turing-way.org/reproducible-research/renv/"><strong>The Turing Way</strong><span>Environment capture for reproducible research.</span></a> <a class="env-atlas-link" href="https://docs.docker.com/guides/python/containerize/"><strong>Docker: Python app</strong><span>Use a whole-runtime boundary.</span></a> </div> </div> </div> --- # Thank You! <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; margin-top: 4rem;"> <h3 style="margin-bottom: 2rem; font-size: 2em;">Questions?</h3> <div style="text-align: center;"> <img src="/assets/slides/2026-05-21-python-env/mohsenhariri-github-io-slides-html.webp" alt="SCIPE Workshop QR Code" style="width: 27rem; max-width: 100%; height: auto; margin: 2rem auto;" /> </div> <div style="font-size: 1.5em; font-weight: bold; text-align: center; margin-top: 2rem; opacity: 0.95;"> Now let's start coding! </div> </div> </div>