Skip to content

Python line counter with snapshots, SQLite DB + tkinter GUI

Notifications You must be signed in to change notification settings

Coverfish/line-counter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Line Counter Snapshot Tool 🧮

A small, slightly overengineered line & function counter that tracks how your project grows (and mutates) over time.

It now:

  • Counts lines for multiple languages
  • Stores history in SQLite
  • Lets you pick exactly which files/folders count
  • Shows a function breakdown per file
  • Lets you delete old snapshots from a nice little list
  • And, of course, has more features, more buttons, and more bugs than ever before 🎉

Credits

  • Code written by ChatGPT (GPT-5.1 Thinking).
  • Human supervisor, button-clicker, and chaos director: Coverfish.
  • Coverfish claims:

    “I have no idea what I’m doing.”
    which is still the core design philosophy of this project.


What it does (now)

On every run, python linecounter.py:

  1. Figures out your project root:

    • The script lives somewhere like: project_root/code/python linecounter.py
    • It scans one level above that (i.e. project_root), recursively.
  2. Discovers all files with supported extensions (see below), skipping big junk like .git, venv, node_modules, etc.

  3. Applies your file selection (from the “Choose files” tab) so only the files you care about are counted.

  4. For each selected file, counts:

    • total lines
    • non-empty lines
  5. Saves a snapshot of those counts into line_history.db (SQLite).

  6. Only creates a new snapshot if something actually changed since the last one.

  7. Collects functions from selected files (Python, C/C++, JavaScript).

  8. Opens a GUI window with four tabs:

    • Snapshots (F1) – Text summary + snapshot list (with delete).
    • Graph (F2) – Horizontal bar chart showing line diffs between snapshots.
    • Functions (F3) – Per-file function list with line numbers.
    • Choose files (F4) – Tree of your project where you can tick/untick files.

If nothing changed, it politely reuses the last snapshot instead of bloating your DB with identical copies.


Tabs overview

F1 – Snapshots

The Snapshots tab is split:

  • Left side:
    A big, colorized text view of all snapshots (newest first by default), showing:

    • Snapshot number and timestamp (and weekday labels like “MONDAY” for the last snapshot of each day)
    • Per-file:
      • total lines
      • non-empty lines
      • code percentage
    • Totals per snapshot at the bottom.
  • Right side:

    • Top: A scrollable list of snapshots in a Treeview:
      • Rows like: Snapshot 26 - 2025-12-11T22:42:17 | Thursday
      • Newest snapshots at the top.
      • You can select one or many (Ctrl/Shift click).
    • Bottom: A big button:
      “Delete selected snapshots”
      This will:
      • Delete the selected snapshots from the SQLite DB
      • Refresh the left text view
      • Refresh the Graph tab, and keep navigation in sync

So yes: you now have a built-in snapshot trash can. Use with power and regret.


F2 – Graph

The Graph tab shows a horizontal bar chart for the currently selected snapshot:

  • It compares the current snapshot to the previous one and displays, per file:
    • baseline lines (previous snapshot)
    • newly added lines
    • removed lines
  • Legend explains the colors:
    • Blue: baseline
    • Red: added
    • Green: removed
  • Totals (total lines / non-empty lines) are shown at the top.

Navigation:

  • Up Arrow / ▲ / “newer snapshot” – move to a newer snapshot
  • Down Arrow / ▼ / “older snapshot” – move to an older snapshot
  • Also controlled by the buttons in the Graph tab.

It auto-sizes vertically and has its own scrollbar, so very large projects don’t completely murder your monitor.


F3 – Functions

The Functions tab scans only the currently selected files (from F4) and shows:

  • A total function count across all files
  • For each file:
    • File path + number of functions
    • Each function name
    • The line number where the function is defined

Color scheme:

  • Total header: bright green
  • File headers: blue
  • Function names: VS-Code-ish yellow
  • Line numbers: green
  • Background: dark theme (your eyes are welcome)

What counts as a “function”?

Right now:

  • Python (.py)
    • Uses the real Python AST (ast module)
    • Detects:
      • Top-level functions
      • Methods inside classes
      • Nested functions
      • Async functions
  • JavaScript (.js) (heuristic)
    • Recognises patterns like:
      • function myFunc(...) {
      • export function myFunc(...) {
      • const myFunc = function(...) {
      • const myFunc = (...) => { ... }
  • C / C++ (.c, .h, .cpp, .hpp) (also heuristic)
    • Looks for lines that look like function definitions with { on the same line
    • Skips obvious preprocessor lines (#include, #define, etc.)

HTML and CSS are line-counted but not function-counted (they kind of don’t have “functions” in this sense, only chaos).

Heuristics mean it might miss some exotic definitions or get confused by weird formatting, but for “what do I even have in this codebase?” it’s surprisingly useful.


F4 – Choose files

This is the project selector brain of the whole thing.

  • Shows a tree view of your project starting at the project root (one level above the folder containing python linecounter.py).
  • Each file line looks like:
    • ☑ code/main.py
    • ☐ code/some_other_file.cpp
  • Behaviour:
    • Click the triangle next to a folder to expand/collapse it.
    • Click a file row to toggle that file’s inclusion.
    • Clicking on a folder can toggle all its descendants (depending on the exact version you’re running).
  • Your choices are saved in the DB (file_selection table), so the next time you run:
    • Only those files are:
      • counted in snapshots
      • shown in the functions tab

This lets you, for example, exclude things like:

  • auto-generated code
  • external libs
  • one particularly cursed prototype folder

…without touching SUPPORTED_EXTENSIONS.


Which files are counted?

There are two related but different concepts:

1. Line counting

These extensions are currently included in line counting:

SUPPORTED_EXTENSIONS = {
    ".py", ".c", ".h", ".cpp", ".hpp",
    ".html", ".css", ".js",
}

So line stats are gathered for:

  • Python (.py)
  • C / C++ (.c, .h, .cpp, .hpp)
  • HTML (.html)
  • CSS (.css)
  • JavaScript (.js)

…and anything else you decide to add to that set.

Plus, the “Choose files” tree lets you narrow this down further.

2. Function counting

Function detection is currently implemented for:

  • Python: .py
  • JavaScript: .js
  • C / C++: .c, .h, .cpp, .hpp

HTML and CSS files are ignored by the function counter (on purpose).


Requirements

  • Python 3.10+
  • Standard library only:
    • pathlib
    • sqlite3
    • tkinter
    • ast
    • os
    • re

On some Linux distros you may need to install tkinter manually:

sudo apt install python3-tk

No pip install required. No virtualenv required.
(But you’ll probably end up with one anyway, because that’s life.)


Installation

git clone https://github.com/Coverfish/line-counter.git
cd line-counter

(Optional) Test if tkinter works:

python -m tkinter

If a small demo window appears, you’re good.


Usage

The script expects something like this structure:

your-project/
    code/
        python linecounter.py
    something_else/
    more_code/

You run it from inside code/ (or via full path), and it will scan one level up (your-project/) recursively.

Run:

python "python linecounter.py"

On each run it will:

  1. Discover files from project root.
  2. Apply your saved file selection.
  3. Count lines and compare with the last snapshot.
  4. Only create a new snapshot if there are changes.
  5. Collect functions from the selected files.
  6. Open the GUI with all four tabs.

The database line_history.db lives next to python linecounter.py (in the code/ folder).


Known features / known bugs

  • Feature: it works.
  • Bug: sometimes it works too much.
  • Feature: supports multiple languages.
  • Bug: those languages did not ask for this.

If it:

  • Counts the wrong thing → you have a graph of your mistakes.
  • Misses a function → maybe that function deserved it.
  • Breaks completely → you get to keep both pieces.

License / “Legal stuff” (still kind of)

This project is basically:

Free to use in any way you see fit.

You can:

  • Copy it
  • Modify it
  • Embed it into your own tools
  • Use it to impress/horrify teammates
  • Sacrifice it to the refactoring gods

There is no warranty of any kind.

If this script deletes all your snapshots because you mis-clicked the big button, that’s between you and your backups.

If you want a more official label, you can mentally treat this as:

Public domain / do whatever you want.


Screenshots

(Old screenshots still apply, but now imagine extra tabs and more chaos.)

Line Counter GUI – Snapshots Line Counter GUI – Graph Line Counter GUI – More Graph Line Counter GUI – Even More Graph Line Counter GUI – Screenshot 5 Line Counter GUI – Screenshot 6

About

Python line counter with snapshots, SQLite DB + tkinter GUI

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages