3 A library
Build it yourself. Read the tutorial is the other way to read this part.
If you start at this part, make your clone as Get the project says, and then run this command. It puts in your clone the files that this part starts from. A file that the project deleted before this part stays, so delete it if git check lists it:
git rm -rq --cached --ignore-unmatch -- :/ && git restore --source d6f47209c66d --staged --worktree -- :/just setuptop keeps the most common words of any counts. Another program that counts words could use it too. So it goes
into a library of its own, talib, in the same workspace. A workspace is a set of packages that share one
uv.lock.
The code before this part. The code after it.
3.1 A library, with uv init
uv init --lib makes a library. In a folder of a project, it also makes the library a member of the project's
workspace. --author-from none leaves out the name of the author, which uv would take from your git settings.
uv init --lib --author-from none packages/talibuv.lock does not name talib yet, so it is out of date until the next move. A uv run would lock it again, so the
check reads the file:
grep -A2 'tool.uv.workspace' pyproject.tomlIt prints the table [tool.uv.workspace], with members = [ and "packages/talib", under it.
Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:
git check f154823215afIf you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:
git restore --source d6f47209c66d --staged -- :/ && git restore --source f154823215af --staged --worktree -- :/What changed
packages/talib/README.md: empty, for the words about the library. New, 0 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/pyproject.toml: the project of the library. New, 11 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/src/talib/__init__.py: a first function,hello. New, 2 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/src/talib/py.typed: empty, to say that the library has types. New, 0 lines. It comes fromuv init --lib --author-from none packages/talib. The file.pyproject.toml: the workspace, with talib as its member. 5 lines added. It comes fromuv init --lib --author-from none packages/talib. The file.- look at
"packages/talib",
- look at
The diff that uv init --lib --author-from none packages/talib makes in packages/talib/pyproject.toml
@@ -0,0 +1,11 @@
+[project]
+name = "talib"
+version = "0.1.0"
+description = "Add your description here"
+readme = "README.md"
+requires-python = ">=3.12"
+dependencies = []
+
+[build-system]
+requires = ["uv_build>=0.12.13,<0.13.0"]
+build-backend = "uv_build"The diff that uv init --lib --author-from none packages/talib makes in packages/talib/src/talib/__init__.py
@@ -0,0 +1,2 @@
+def hello() -> str:
+ return "Hello from talib!"The diff that uv init --lib --author-from none packages/talib makes in pyproject.toml
@@ -28,3 +28,8 @@ line-length = 100
[tool.uv]
default-groups = ["dev", "docs"]
+
+[tool.uv.workspace]
+members = [
+ "packages/talib",
+]3.2 tally depends on talib
tally cannot import talib until it depends on it. uv add finds talib in the workspace, and takes it from there:
uv add talibuv run python -c "import talib; print(talib.hello())"It prints Hello from talib!.
Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:
git check de7bf1a4a64cIf you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:
git restore --source f154823215af --staged -- :/ && git restore --source de7bf1a4a64c --staged --worktree -- :/What changed
pyproject.toml: talib, from the workspace. 4 lines added. It comes fromuv add talib. The file.- look at
talib = { workspace = true }
- look at
uv.lock: talib, as a member of the workspace. 16 lines added, 1 removed. It comes fromuv add talib. The file.
The diff that uv add talib makes in pyproject.toml
@@ -6,6 +6,7 @@ readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"tabulate>=0.9,<0.10",
+ "talib",
]
[project.scripts]
@@ -33,3 +34,6 @@ default-groups = ["dev", "docs"]
members = [
"packages/talib",
]
+
+[tool.uv.sources]
+talib = { workspace = true }3.3 top goes into talib
top is still in tally, and talib has only hello. One patch moves top across, in both packages.
Apply the patch to packages/talib/src/talib/__init__.py, from the top of the project:
curl -fsSL https://github.com/rahuldave/tally/commit/909df18d1c02f51f42154cdded5a8ef515482057.diff | git apply --include=packages/talib/src/talib/__init__.pyApply the patch to src/tally/__init__.py, from the top of the project:
curl -fsSL https://github.com/rahuldave/tally/commit/909df18d1c02f51f42154cdded5a8ef515482057.diff | git apply --include=src/tally/__init__.pyIn packages/talib/src/talib/__init__.py, the patch puts a docstring and top in place of hello. In
src/tally/__init__.py, it removes top, and adds from talib import top under from tabulate import tabulate.
uv run python -m unittest discover -s tests -qAll four tests pass.
head -4 packages/talib/src/talib/__init__.py"""talib: small helpers for the counts of words."""
def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:It prints the docstring of the library, two blank lines, and the first line of top.
Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:
git check 909df18d1c02If you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:
git restore --source de7bf1a4a64c --staged -- :/ && git restore --source 909df18d1c02 --staged --worktree -- :/What changed
packages/talib/src/talib/__init__.py:top, in place ofhello. 6 lines added, 2 removed. The file.- look at
def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
- look at
src/tally/__init__.py:topcomes from talib. 1 line added, 5 removed. The file.- look at
from talib import top
- look at
The patch to packages/talib/src/talib/__init__.py
@@ -1,2 +1,6 @@
-def hello() -> str:
- return "Hello from talib!"
+"""talib: small helpers for the counts of words."""
+
+
+def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
+ "The n most common words, most common first."
+ return sorted(counts.items(), key=lambda pair: (-pair[1], pair[0]))[:n]The patch to src/tally/__init__.py
@@ -3,6 +3,7 @@
import sys
from tabulate import tabulate
+from talib import top
def count(text: str) -> dict[str, int]:
@@ -13,11 +14,6 @@ def count(text: str) -> dict[str, int]:
return counts
-def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
- "The n most common words, most common first."
- return sorted(counts.items(), key=lambda pair: (-pair[1], pair[0]))[:n]
-
-
def main() -> None:
"Count the words of a file, or of the standard input. Options: --top N, and --table."
args = sys.argv[1:]