4 One dependency less

Read the tutorial. Build it yourself is the other way to read this part.

just setup

tally uses tabulate for one table, of two columns. A few lines of its own draw the same table, and the project needs one package less.

The code before this part. The code after it.

4.1 tally draws its own table

A function table draws the header, the rule of dashes, and the rows, with the same widths as tabulate.

A patch to src/tally/__init__.py.

src/tally/__init__.py has a function table, and main prints table(rows). Nothing imports tabulate now.

uv run tally --top 3 --table data/corpus.txt

It prints the same table as tabulate printed. It has the header word and times, a rule of dashes, and three rows.

What changed

  • src/tally/__init__.py: the function table, in place of tabulate. 10 lines added, 2 removed. The file.
    • look at def table(rows: list[tuple[str, int]]) -> str:
The diff of src/tally/__init__.py
@@ -2,7 +2,6 @@
 
 import sys
 
-from tabulate import tabulate
 from talib import top
 
 
@@ -14,6 +13,15 @@ def count(text: str) -> dict[str, int]:
     return counts
 
 
+def table(rows: list[tuple[str, int]]) -> str:
+    "The rows under a header and a rule: the words on the left, the counts on the right."
+    left = max([len("word") + 2, *(len(word) for word, _ in rows)])
+    right = max([len("times") + 2, *(len(str(times)) for _, times in rows)])
+    lines = [f"{'word':<{left}}  {'times':>{right}}", f"{'-' * left}  {'-' * right}"]
+    lines += [f"{word:<{left}}  {times:>{right}}" for word, times in rows]
+    return "\n".join(lines)
+
+
 def main() -> None:
     "Count the words of a file, or of the standard input. Options: --top N, and --table."
     args = sys.argv[1:]
@@ -29,7 +37,7 @@ def main() -> None:
     counts = count(text)
     rows = top(counts, n) if n else sorted(counts.items())
     if as_table:
-        print(tabulate(rows, headers=["word", "times"]))
+        print(table(rows))
         return
     for word, times in rows:
         print(times, word)

This change on GitHub. The code after it.

4.2 tabulate goes

Nothing imports tabulate now, but the project still depends on it. uv remove takes it out of pyproject.toml and uv.lock:

This change came from running uv remove tabulate.

pyproject.toml no longer lists tabulate, and uv.lock no longer has it.

uv run python -m unittest discover -s tests -q

All four tests pass, without tabulate.

What changed

  • pyproject.toml: tabulate is gone. 0 lines added, 1 removed. It comes from uv remove tabulate. The file.
  • uv.lock: tabulate is gone. 1 line added, 14 removed. It comes from uv remove tabulate. The file.
The diff of pyproject.toml
@@ -5,7 +5,6 @@ description = "Count the words in a text"
 readme = "README.md"
 requires-python = ">=3.12"
 dependencies = [
-    "tabulate>=0.9,<0.10",
     "talib",
 ]
 

This change on GitHub. The code after it.