0 Where it starts

just setup

A project needs a place for its code, a command to run, and the same packages for everyone. tally is a uv project, as uv init --package makes one. In pyproject.toml, the table [project.scripts] makes a command called tally, and the table [build-system] lets uv install the project into its own .venv. .python-version and uv.lock are in git, so every learner gets the same Python and the same packages.

just setup ran uv sync, which made .venv. git ignores .venv, so it stays as it is when the code changes.

uv run tally
ls -a

The command prints tally: nothing to count yet. The project has a command, and the command has no work.

# in the project, where you started
git log --oneline --decorate --all | head -20

Ask: what should "the" and "The" count as?

What changed

  • .gitignore: the files that git does not hold, such as .venv. New, 10 lines. The file.
  • .python-version: the version of Python that uv uses. New, 1 line. The file.
  • README.md: one line about tally. New, 3 lines. The file.
  • justfile: the recipes, with setup first. New, 15 lines. The file.
  • pyproject.toml: the project, and the table [project.scripts] that makes the command tally. New, 14 lines. The file.
    • look at tally = "tally:main"
  • src/tally/__init__.py: main, which has nothing to count yet. New, 5 lines. The file.
  • src/tally/__main__.py: lets python -m tally run main too. New, 3 lines. The file.
  • uv.lock: the exact packages, the same for every learner. New, 8 lines. The file.
The diff of .gitignore
@@ -0,0 +1,10 @@
+# Python-generated files
+__pycache__/
+*.py[oc]
+build/
+dist/
+wheels/
+*.egg-info
+
+# Virtual environments
+.venv
The diff of .python-version
@@ -0,0 +1 @@
+3.12
The diff of README.md
@@ -0,0 +1,3 @@
+# tally
+
+Count the words in a text.
The diff of justfile
@@ -0,0 +1,15 @@
+# The recipes of tally. Each one runs through uv, in the project's own environment.
+default:
+    @just --list
+
+# Make the environment of this step: the first command of every step
+setup:
+    uv sync
+
+# Count the words of a file
+run file:
+    uv run tally {{ file }}
+
+# Run the tests
+test:
+    uv run python -m unittest discover -s tests -q
The diff of pyproject.toml
@@ -0,0 +1,14 @@
+[project]
+name = "tally"
+version = "0.1.0"
+description = "Count the words in a text"
+readme = "README.md"
+requires-python = ">=3.12"
+dependencies = []
+
+[project.scripts]
+tally = "tally:main"
+
+[build-system]
+requires = ["uv_build>=0.12.13,<0.13.0"]
+build-backend = "uv_build"
The diff of src/tally/__init__.py
@@ -0,0 +1,5 @@
+"""tally: count the words in a text."""
+
+
+def main() -> None:
+    print("tally: nothing to count yet")
The diff of src/tally/__main__.py
@@ -0,0 +1,3 @@
+from tally import main
+
+main()

The code.