Labs and the skills they use

Before a lab, find the Python skills it needs and the short video for each one; after it, look back and see what you can now do.

Undergraduate labs

Lab 3·Good, Bad and Ugly — Honest vs Misleading Visualizations

Steps
  1. Part 1Anscombe's Quartet
  2. Part 2Lie Factor and honest redesign
  3. Part 3Four versions of one dataset
  4. Part 4Systematic EDA on World Bank data
  5. AI expansionWrite the prompt, run the code, check it against your own result
  6. Part 5Push to GitHub with the P.R.I.M.E. README
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 min
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcomingMissing values: find them, drop them, fill themcoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 4·Robust Statistics — When One Row Moves the Answer

Steps
  1. Part 1Robust vs non-robust
  2. Part 2Tukey fences
  3. Part 3Isolation Forest
  4. ExtensionContamination experiment
  5. Challengeflag_outliers(), their first function
  6. AI expansionWrite the prompt, run the code, check it against your own result
  7. CloseTake-home and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 min
Setup & load
Read a CSV from a link and take a first lookcomingData that isn't a CSV: FRED with a secret key, and built-in datasetscoming
Machine learning
scikit-learn's pattern: build, fit, predictcomingfirst time you need this
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 5·Probability & Simulation — When Intuition Is Wrong

Steps
  1. Part 1Coin flips and the Law of Large Numbers
  2. Part 2Monty Hall
  3. Part 3Bayes — the 99% accurate test
  4. Part 4Monte Carlo Value at Risk
  5. ExtensionMonte Carlo convergence rate
  6. AI expansionWrite the prompt, run the code, check it against your own result
  7. CloseSubmission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncomingCollect results in a loop: range, append, and list comprehensions4 minfirst time you need this
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcomingQuick charts straight from pandas: df.plot()coming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 7·Estimation & Bootstrapping — How Uncertain Is the Median?

Steps
  1. SetupStep 1–2 — seed, then a download
  2. Part 1Standard deviation vs standard error
  3. Part 2The parametric interval
  4. Part 3The bootstrap by hand — where it fails, then where it earns it
  5. Part 4scipy, and the two blanks
  6. ExtensionDoes a 95% interval actually cover 95%?
  7. ChallengeAn estimate with no formula
  8. AI expansionWrite the prompt, run the code, check it against your own result
  9. CloseSubmission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 minCollect results in a loop: range, append, and list comprehensions4 min
Setup & load
Read a CSV from a link and take a first lookcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Your own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 8·Hypothesis Testing — Was the Job Training Worth It?

Steps
  1. SetupStep 1 — an install, then a download
  2. Part 1The LaLonde data, and the raw gap
  3. Part 2One sample, then two
  4. Part 3How big, and could we have seen it
  5. Part 4Five subgroups, two blanks
  6. Write itWelch's t from six numbers
  7. ExtensionWhat α and power actually are
  8. ChallengeThe replication crisis, simulated
  9. CloseREADME and submission
Skills you need
Everywhere
Setup & load
Read a CSV from a link and take a first lookcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Your own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcomingQuick charts straight from pandas: df.plot()coming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 9·A/B Testing — Designing the Data-Generating Process

Steps
  1. SetupStep 1 — one install, one seed
  2. Part 1The experimental benchmark, and what losing it costs
  3. Part 2Permutation for the p-value, bootstrap for the size
  4. Part 3Power, before any data
  5. Part 4Cookie Cats: the decision
  6. Write itn_needed(), then a rerun sized for Cookie Cats
  7. ExtensionMetric design, and the peeking problem
  8. ChallengeDesign and simulate a full A/B test
  9. CloseREADME and submission
Skills you need
Everywhere
Setup & load
Read a CSV from a link and take a first lookcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Your own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcomingQuick charts straight from pandas: df.plot()coming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 10·Correlation & Causality — Which Story Made This Scatterplot?

Steps
  1. SetupStep 1 — imports and one seeded generator
  2. Part 1Three worlds, one scatterplot
  3. Part 2Writing the claim down, then the good control
  4. Part 3The control that creates bias
  5. Part 4M-bias, then LaLonde against the benchmark
  6. Write itcoef_on_d(), then the path closed by u1
  7. ExtensionSample size does not cure bias
  8. ChallengeLet the graph choose the controls
  9. CloseREADME and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 min
Clean & reshape
Join two tables: .merge() and SQL's JOINcoming
Regression & time series
Fit a regression with statsmodels: sm.OLS(y, sm.add_constant(X)).fit()comingfirst time you need thisRead regression results: coefficients, standard errors, intervalscomingfirst time you need this
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingRegression by formula: smf.ols('y ~ x', data=df) and clustered SEscomingfirst time you need this

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 11·SQL for Economists — The Same Operations, A Different Grammar

Steps
  1. SetupStep 1 — a pip install, then DuckDB
  2. Part 1You already know this
  3. Part 2The cardinality trap
  4. Part 3Aggregating without collapsing
  5. Part 4NULL is not a value, and data you never downloaded
  6. ExtensionFix the fan-out: aggregate before you join
  7. ChallengeRead a query you did not write
  8. AI expansionWrite the prompt, run the code, check it against your own result
  9. CloseREADME and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 min
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingJoin two tables: .merge() and SQL's JOINcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingDefensive code: raise, assert and try/exceptcomingQuick charts straight from pandas: df.plot()comingRegression by formula: smf.ols('y ~ x', data=df) and clustered SEscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 12·Predictive Modeling — The Same Machinery, A New Scorecard

Steps
  1. SetupStep 1 — imports and two seeds
  2. Part 1One predictor, three routes to the same line
  3. Part 2R-squared, and why it cannot fall
  4. Part 3The test set
  5. Part 4The two jobs
  6. Write itholdout_rmse(), then median income alone
  7. ExtensionOkun's Law: the coefficient is the result
  8. ChallengeWhere the line breaks: the $500,001 ceiling
  9. CloseREADME and submission
Skills you need
Setup & load
Read a CSV from a link and take a first lookcomingData that isn't a CSV: FRED with a secret key, and built-in datasetscoming
Clean & reshape
Dates: parse_dates, .dt.year, and a monthly gridcomingMissing values: find them, drop them, fill themcoming
Regression & time series
Fit a regression with statsmodels: sm.OLS(y, sm.add_constant(X)).fit()comingRead regression results: coefficients, standard errors, intervalscomingTime series: shift and rolling, then STL, ARIMA and Prophetcomingfirst time you need thisRobust standard errors and residuals: cov_type and res.residcomingfirst time you need this
Machine learning
scikit-learn's pattern: build, fit, predictcomingSplit the data: train_test_split and stratifycoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscomingScore a model: RMSE, R-squared and sklearn.metricscomingfirst time you need this
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingRegression by formula: smf.ols('y ~ x', data=df) and clustered SEscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 13·Multivariate OLS — What "Controlling For" Actually Does

Steps
  1. SetupStep 1 — imports and one seeded generator
  2. Part 1Omitted-variable bias, with the truth known
  3. Part 2Frisch-Waugh-Lovell
  4. Part 3The control that creates bias, and two that cannot be told apart
  5. Part 4Interactions
  6. ExtensionChoosing what goes in: a specification table by hand
  7. ChallengeSign the bias before you run it
  8. AI expansionWrite the prompt, run the code, check it against your own result
  9. CloseREADME and submission
Skills you need
Everywhere
.loc and .iloc: rows by label or by positioncoming
Setup & load
Read a CSV from a link and take a first lookcoming
Regression & time series
Fit a regression with statsmodels: sm.OLS(y, sm.add_constant(X)).fit()comingRead regression results: coefficients, standard errors, intervalscomingRobust standard errors and residuals: cov_type and res.residcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingRegression by formula: smf.ols('y ~ x', data=df) and clustered SEscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 14·OLS Diagnostics — When the Standard Error Is Lying

Steps
  1. SetupStep 1 — imports and one seeded generator
  2. Part 1The coefficient survives, the interval does not
  3. Part 2Reading residuals: four pictures, two tests
  4. Part 3Influence: which number one row moves
  5. Part 4Real data: California Housing, classical and HC3 side by side
  6. Write ithc3_se(), then three sentences
  7. ExtensionInfluence in real data, and when robust is not enough
  8. ChallengeThe specification that passes everything
  9. CloseREADME and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncoming.loc and .iloc: rows by label or by positioncomingWrite a small function: def, return, docstring4 minCollect results in a loop: range, append, and list comprehensions4 min
Setup & load
Data that isn't a CSV: FRED with a secret key, and built-in datasetscoming
Regression & time series
Fit a regression with statsmodels: sm.OLS(y, sm.add_constant(X)).fit()comingRead regression results: coefficients, standard errors, intervalscomingRobust standard errors and residuals: cov_type and res.residcoming
Machine learning
scikit-learn's pattern: build, fit, predictcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcomingRegression by formula: smf.ols('y ~ x', data=df) and clustered SEscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 15·The Bias-Variance Tradeoff — Watching a Model Overfit

Steps
  1. SetupStep 1 — imports and the seed
  2. Part 1Two ways to be wrong
  3. Part 2The curve that misleads
  4. Part 3Cross-validation, and the spread across folds
  5. Part 4The selection you did not account for
  6. Write itkfold_mse(), then 10 folds
  7. ExtensionMore data instead of less complexity
  8. ChallengeWhere the tradeoff is not a curve
  9. CloseREADME and submission
Skills you need
Machine learning
scikit-learn's pattern: build, fit, predictcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscomingCross-validation: KFold by hand, then cv=5comingfirst time you need this
Graduate extras
Your own module: %%writefile, import, and importlib.reloadcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 16·Regularization — Buying Bias to Sell Variance

Steps
  1. SetupStep 1 — the scikit-learn upgrade, imports and the seed
  2. Part 1Where OLS runs out
  3. Part 2The path, and λ by cross-validation
  4. Part 3What it recovered
  5. Part 4Correlated predictors
  6. ExtensionElastic Net
  7. ChallengeStandardisation is not optional
  8. AI expansionWrite the prompt, run the code, check it against your own result
  9. CloseREADME and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncomingCollect results in a loop: range, append, and list comprehensions4 min
Machine learning
scikit-learn's pattern: build, fit, predictcomingSplit the data: train_test_split and stratifycomingScale, then fit: StandardScaler and make_pipelinecoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscomingScore a model: RMSE, R-squared and sklearn.metricscomingCross-validation: KFold by hand, then cv=5coming
Graduate extras
Function signatures: type hints, defaults and docstringscomingYour own module: %%writefile, import, and importlib.reloadcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Graduate labs

Lab 3·Pipeline Health Check — Finding Corruption Through EDA

Steps
  1. SetupBefore you start
  2. Part 0Build it first
  3. Part 1The five planted bugs
  4. Part 2Distribution shift
  5. Part 3Manual vs automated
  6. Part 4eda_utils.py
  7. AI expansionWrite the prompt, run the code, check it against your own result
  8. CloseAI expansion and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncomingWrite a small function: def, return, docstring4 min
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcomingMissing values: find them, drop them, fill themcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 4·Robust Statistics — Three Bugs in an Outlier Pipeline

Steps
  1. SetupBefore you start
  2. Part 0Build it first
  3. Part 1The three bugs
  4. Part 2OutlierDetector module
  5. Part 3Why the methods disagree
  6. AI expansionWrite the prompt, run the code, check it against your own result
  7. CloseAI expansion and submission
Skills you need
Everywhere
Filter rows with a mask: &, |, ~ and the brackets around each conditioncomingWrite a small function: def, return, docstring4 min
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcomingMissing values: find them, drop them, fill themcoming
Machine learning
scikit-learn's pattern: build, fit, predictcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 5·Probability & Monte Carlo — The VaR That Was Not Wrong Yet

Steps
  1. SetupBefore you start
  2. Part 0Build it first
  3. Part 1Find the flaw
  4. Part 2Fix it: VaR and ES
  5. Part 3Antithetic variates
  6. Part 4risk_metrics.py
  7. AI expansionWrite the prompt, run the code, check it against your own result
  8. CloseAI expansion and submission
Skills you need
Everywhere
.loc and .iloc: rows by label or by positioncomingCollect results in a loop: range, append, and list comprehensions4 min
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcomingMissing values: find them, drop them, fill themcoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 6·Experiment Design Audit — Power, Selection, and Weighting

Steps
  1. SetupBefore you start
  2. Part 1Power
  3. Part 2Selection bias
  4. Part 3IPW
  5. Write itWrite it yourself
  6. ExtensionMeng's identity
  7. CloseSubmission
Skills you need
Everywhere
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcoming
Machine learning
Split the data: train_test_split and stratifycoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 7·Estimation & Bootstrapping — Diagnosing Broken Confidence Intervals

Steps
  1. SetupOne download, two seeds
  2. Diagnosis 1The interval of width zero
  3. Diagnosis 2The interval that lies quietly
  4. Diagnosis 3The interval that is far too narrow
  5. Ship ItThe repair as a module, and the optional flipped panel
  6. AI expansionWrite the prompt, run the code, check it against your own result
  7. ExtensionThe Bayesian bootstrap
  8. ChallengeThe fourth failure mode, take-home
  9. CloseREADME and submission
Skills you need
Everywhere
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 8·Hypothesis Testing — Diagnosing Underpowered Studies and P-Hacking

Steps
  1. SetupImports and one seed
  2. Diagnosis 1The underpowered study
  3. Diagnosis 2The p-hacked result
  4. Write itbh_reject, from an empty cell
  5. Modulesrc/power_utils.py, given
  6. ExtensionFour tests, one sample
  7. ChallengeBrodeur's camel
  8. CloseREADME and submission
Skills you need
Setup & load
Read a CSV from a link and take a first lookcoming
Clean & reshape
groupby: one number per groupcomingDates: parse_dates, .dt.year, and a monthly gridcoming
Evaluate & report
Line up a results table: <, > and widths in f-stringscoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.

Lab 9·A/B Testing — Diagnosing Experimental Failures

Steps
  1. SetupImports and one seed
  2. Part 1Broken CUPED: three bugs
  3. Part 2Two sample ratio mismatches
  4. Part 3SUTVA in a marketplace
  5. Part 4Bayesian A/B test
  6. Write itbayes_ab, from an empty cell
  7. Modulesrc/cuped_utils.py, given
  8. ExtensionThe peeking problem
  9. ChallengeCUPED on LaLonde
  10. CloseREADME and submission
Skills you need
Regression & time series
Fit a regression with statsmodels: sm.OLS(y, sm.add_constant(X)).fit()coming
Machine learning
Split the data: train_test_split and stratifycoming

and the everyday basics: Colab, imports, variables, reading an error, f-strings, one bracket or two, a first chart, loops, more charts, numpy arrays and seeds.