Skip to content

Commit b5515c3

Browse files
committed
Py4DS compiles with uv!
1 parent d62473c commit b5515c3

27 files changed

+3247
-349
lines changed

.pre-commit-config.yaml

+13-21
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,18 @@ repos:
1313
entry: nbstripout
1414
language: python
1515
types: [jupyter]
16-
- repo: https://github.com/psf/black
17-
rev: 22.3.0
16+
- repo: https://github.com/astral-sh/ruff-pre-commit
17+
# Ruff version.
18+
rev: v0.4.1
1819
hooks:
19-
- id: black
20-
name: black
21-
description: 'applies black formatter to .py files'
22-
entry: black
23-
language: python
24-
types: [python]
25-
- id: black-jupyter
26-
name: black-jupyter
27-
description:
28-
"Black: The uncompromising Python code formatter (with Jupyter Notebook support)"
29-
entry: black
30-
language: python
31-
minimum_pre_commit_version: 2.9.2
32-
require_serial: true
20+
# Run the linter.
21+
- id: ruff
22+
types_or: [python, pyi, jupyter]
23+
args: [ --fix ]
24+
- id: ruff
25+
types_or: [python, pyi, jupyter]
26+
name: sort imports with ruff
27+
args: [--select, I, --fix]
28+
# Run the formatter.
29+
- id: ruff-format
3330
types_or: [python, pyi, jupyter]
34-
additional_dependencies: [".[jupyter]"]
35-
- repo: https://github.com/pycqa/flake8
36-
rev: 3.9.2 # pick a git hash / tag to point to
37-
hooks:
38-
- id: flake8

Dockerfile

+14-21
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,31 @@
1-
# DOCKERFILE for Coding for Economists
2-
# Please note that you will need a lot of RAM dedicated to Docker to build this image (15Gb+, change this in your docker settings)
1+
# DOCKERFILE for Python for Data Science
32

4-
# Set base image (this also loads the Alpine Linux operating system)
5-
FROM continuumio/miniconda3:4.10.3-alpine
3+
# Set base image
4+
FROM python:3.10-slim-bookworm
65

76
WORKDIR /app
87

98
# Update Linux package list and install some key libraries, including latex
10-
RUN apk update && apk add openssl graphviz \
11-
nano texlive alpine-sdk build-base graphviz-dev \
12-
bash
9+
RUN apt-get -y update && apt-get install -y openssl graphviz \
10+
nano texlive graphviz-dev \
11+
bash build-essential git
1312

1413
# change default shell from ash to bash
1514
RUN sed -i -e "s/bin\/ash/bin\/bash/" /etc/passwd
1615

17-
# Install mamba
18-
RUN conda install mamba -n base -c conda-forge
16+
# Create the environment:
17+
COPY uv.lock .
18+
COPY pyproject.toml .
1919

20-
# Ensure pip's setuptools is latest
21-
RUN pip install --upgrade setuptools wheel
20+
# Install uv
21+
COPY --from=ghcr.io/astral-sh/uv:0.5.14 /uv /bin/uv
2222

23-
# Create the environment:
24-
COPY environment.yml .
2523
# Install everything at once:
26-
RUN mamba env create -f environment.yml
27-
# Do a debug or incremental env install (builds quickly):
28-
# RUN mamba create -n python4DS -c conda-forge python=3.9 numpy pandas -y
29-
30-
# Make RUN commands use the new environment:
31-
SHELL ["conda", "run", "-n", "py4ds2e", "/bin/bash", "-c"]
24+
RUN uv sync --frozen
3225

33-
RUN mamba list
26+
RUN uv pip list
3427

3528
# Copy the current directory contents into the container at /app
3629
COPY . /app
3730

38-
RUN echo "Success building the python4DS container!"
31+
RUN echo "Success building the Python4DS container!"

_config.yml

+17-4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
title: Python for Data Science
55
author: The Py4DS Community
66
logo: logo.png
7-
7+
exclude_patterns: [_build, Thumbs.db, .DS_Store, "**.ipynb_checkpoints", ".venv"]
88
# Force re-execution of notebooks on each build.
99
# See https://jupyterbook.org/content/execute.html
1010
execute:
1111
execute_notebooks: force
1212
timeout: 120
13-
exclude_patterns: [README.md]
13+
exclude_patterns: ["README.md"]
14+
allow_errors: false
15+
nb_output_stderr: show
16+
1417

1518
# Define the name of the latex output file for PDF builds
1619
latex:
@@ -32,9 +35,19 @@ html:
3235
use_issues_button: true
3336
use_repository_button: true
3437
favicon: "favicon.ico" # A path to a favicon image
35-
google_analytics_id: "G-LXJC37BJVX" # A GA id that can be used to track book views.
38+
analytics:
39+
google_analytics_id: "G-LXJC37BJVX" # A GA id that can be used to track book views.
3640

3741
launch_buttons:
3842
colab_url: "https://colab.research.google.com"
3943
notebook_interface: "jupyterlab" # or "classic"
40-
binderhub_url: "https://mybinder.org"
44+
binderhub_url: "https://mybinder.org"
45+
46+
sphinx:
47+
config:
48+
html_js_files:
49+
- https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js
50+
bibtex_reference_style: author_year
51+
suppress_warnings: ["mystnb.unknown_mime_type"]
52+
nb_execution_show_tb: true
53+
nb_execution_raise_on_error: true # Make build fail any content errors (don't want to publish if errors)

categorical-data.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"outputs": [],
2626
"source": [
2727
"# remove cell\n",
28-
"import matplotlib_inline.backend_inline\n",
2928
"import matplotlib.pyplot as plt\n",
29+
"import matplotlib_inline.backend_inline\n",
3030
"\n",
3131
"# Plot settings\n",
3232
"plt.style.use(\"https://github.com/aeturrell/python4DS/raw/main/plot_style.txt\")\n",

communicate-plots.ipynb

+5-9
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"outputs": [],
3838
"source": [
3939
"# remove cell\n",
40-
"import matplotlib_inline.backend_inline\n",
4140
"import matplotlib.pyplot as plt\n",
41+
"import matplotlib_inline.backend_inline\n",
4242
"\n",
4343
"# Plot settings\n",
4444
"plt.style.use(\"https://github.com/aeturrell/python4DS/raw/main/plot_style.txt\")\n",
@@ -52,10 +52,9 @@
5252
"metadata": {},
5353
"outputs": [],
5454
"source": [
55-
"from lets_plot import *\n",
56-
"from lets_plot.mapping import as_discrete\n",
57-
"import pandas as pd\n",
5855
"import numpy as np\n",
56+
"import pandas as pd\n",
57+
"from lets_plot import *\n",
5958
"\n",
6059
"LetsPlot.setup_html()"
6160
]
@@ -1326,17 +1325,14 @@
13261325
}
13271326
],
13281327
"metadata": {
1329-
"interpreter": {
1330-
"hash": "9d7534ecd9fbc7d385378f8400cf4d6cb9c6175408a574f1c99c5269f08771cc"
1331-
},
13321328
"jupytext": {
13331329
"cell_metadata_filter": "-all",
13341330
"encoding": "# -*- coding: utf-8 -*-",
13351331
"formats": "md:myst",
13361332
"main_language": "python"
13371333
},
13381334
"kernelspec": {
1339-
"display_name": "Python 3 (ipykernel)",
1335+
"display_name": ".venv",
13401336
"language": "python",
13411337
"name": "python3"
13421338
},
@@ -1350,7 +1346,7 @@
13501346
"name": "python",
13511347
"nbconvert_exporter": "python",
13521348
"pygments_lexer": "ipython3",
1353-
"version": "3.10.13"
1349+
"version": "3.10.0"
13541350
},
13551351
"toc-showtags": true
13561352
},

data-import.ipynb

-2
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@
181181
"metadata": {},
182182
"outputs": [],
183183
"source": [
184-
"import numpy as np\n",
185-
"\n",
186184
"students[\"age\"] = students[\"age\"].replace(\"five\", 5)\n",
187185
"students[\"age\"]"
188186
]

data-tidy.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
"outputs": [],
3030
"source": [
3131
"# remove cell\n",
32-
"import matplotlib_inline.backend_inline\n",
3332
"import matplotlib.pyplot as plt\n",
33+
"import matplotlib_inline.backend_inline\n",
3434
"\n",
3535
"# Plot settings\n",
3636
"plt.style.use(\"https://github.com/aeturrell/python4DS/raw/main/plot_style.txt\")\n",

data-visualise.ipynb

+1-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@
6868
"metadata": {},
6969
"outputs": [],
7070
"source": [
71-
"import pandas as pd\n",
72-
"from palmerpenguins import load_penguins\n",
7371
"from lets_plot import *\n",
72+
"from palmerpenguins import load_penguins\n",
7473
"\n",
7574
"LetsPlot.setup_html()"
7675
]

databases.ipynb

+12-25
Original file line numberDiff line numberDiff line change
@@ -453,47 +453,39 @@
453453
"import ibis\n",
454454
"\n",
455455
"ibis.options.interactive = True\n",
456-
"connection = ibis.sqlite.connect(Path(\"data/Chinook.sqlite\"))\n",
456+
"connection = ibis.sqlite.connect(\"data/Chinook.sqlite\")\n",
457457
"track = connection.table(\"track\")\n",
458458
"track.head()"
459459
]
460460
},
461461
{
462462
"cell_type": "markdown",
463-
"id": "965cc983",
463+
"id": "6dcd7d71",
464464
"metadata": {},
465465
"source": [
466-
"As an aside, you can list the available tables using"
466+
"Okay, now let's reproduce the following query: \"SELECT albumid, AVG(milliseconds)/1e3/60 FROM track GROUP BY albumid ORDER BY AVG(milliseconds) ASC LIMIT 5;\". We'll use a groupby, a mutate (which you can think of like **pandas**' assign statement), a sort, and then `limit()` to only show the first five entries."
467467
]
468468
},
469469
{
470470
"cell_type": "code",
471471
"execution_count": null,
472-
"id": "58369c80",
472+
"id": "5e5a482b",
473473
"metadata": {},
474474
"outputs": [],
475475
"source": [
476-
"connection.list_tables()"
477-
]
478-
},
479-
{
480-
"cell_type": "markdown",
481-
"id": "6dcd7d71",
482-
"metadata": {},
483-
"source": [
484-
"Okay, now let's reproduce the following query: \"SELECT albumid, AVG(milliseconds)/1e3/60 FROM track GROUP BY albumid ORDER BY AVG(milliseconds) ASC LIMIT 5;\". We'll use a groupby, a mutate (which you can think of like **pandas**' assign statement), a sort, and then `limit()` to only show the first five entries."
476+
"track.group_by(\"AlbumId\").mutate(\n",
477+
" mean_mins_track=track.Milliseconds.mean() / 1e3 / 60\n",
478+
").order_by(\"mean_mins_track\").limit(5)"
485479
]
486480
},
487481
{
488482
"cell_type": "code",
489483
"execution_count": null,
490-
"id": "5e5a482b",
484+
"id": "39c80365",
491485
"metadata": {},
492486
"outputs": [],
493487
"source": [
494-
"track.group_by(\"AlbumId\").mutate(\n",
495-
" mean_mins_track=track.Milliseconds.mean() / 1e3 / 60\n",
496-
").order_by(\"mean_mins_track\").limit(5)"
488+
"track.group_by(\"AlbumId\").mutate(mean_mins_track=track.Milliseconds.mean() / 1e3 / 60)"
497489
]
498490
},
499491
{
@@ -788,7 +780,7 @@
788780
"main_language": "python"
789781
},
790782
"kernelspec": {
791-
"display_name": "Python 3.9.12 ('python4DS')",
783+
"display_name": ".venv",
792784
"language": "python",
793785
"name": "python3"
794786
},
@@ -802,14 +794,9 @@
802794
"name": "python",
803795
"nbconvert_exporter": "python",
804796
"pygments_lexer": "ipython3",
805-
"version": "3.10.12"
797+
"version": "3.10.0"
806798
},
807-
"toc-showtags": true,
808-
"vscode": {
809-
"interpreter": {
810-
"hash": "9d7534ecd9fbc7d385378f8400cf4d6cb9c6175408a574f1c99c5269f08771cc"
811-
}
812-
}
799+
"toc-showtags": true
813800
},
814801
"nbformat": 4,
815802
"nbformat_minor": 5

0 commit comments

Comments
 (0)