Files
lottosight/CLAUDE.md
T
2026-05-23 12:37:01 -04:00

18 KiB
Raw Blame History

LottoSight — Project Documentation

App Overview

Name: LottoSight
Type: Desktop Application
Framework: Python + Tkinter
Database: SQLite (local, zero-config)
Purpose: Analyze historical lottery drawing data and predict next winning numbers using multiple statistical strategies.


Tech Stack

Component Technology
UI Tkinter + ttk
Charts Matplotlib (embedded in Tkinter)
Database SQLite via sqlite3
Data Fetch requests + BeautifulSoup
Analysis collections, statistics, numpy
Scheduler APScheduler
Export openpyxl
Packaging PyInstaller

Supported Games

Game Main Balls Pool Bonus Ball Pool
Powerball 5 169 1 126
Mega Millions 5 170 1 125
Custom config config optional config

Data Sources

Source Game Coverage Method
NY Open Data API Powerball 2010present REST API
NY Open Data API Mega Millions 2002present REST API
Texas Lottery CSV Mega Millions 2003present CSV download

API Endpoints

  • Powerball (NY): https://data.ny.gov/resource/d6yy-54nr.json
  • Mega Millions (NY): https://data.ny.gov/resource/5xaw-6ayf.json
  • Mega Millions (TX): https://www.texaslottery.com/export/sites/lottery/Games/Mega_Millions/Winning_Numbers/download.html

File Structure

lottosight/
├── main.py                  # Entry point, app window, toolbar
├── db/
│   ├── database.py          # SQLite setup, schema, migrations
│   └── models.py            # CRUD operations, duplicate check
├── core/
│   ├── analyzer.py          # All analysis logic
│   ├── predictor.py         # Prediction strategies (5 total)
│   └── fetcher.py           # Fetch logic — auto + manual, all 3 sources
├── ui/
│   ├── dashboard.py         # Home/summary screen
│   ├── history.py           # Draw history browser
│   ├── analysis.py          # Charts and stats screen
│   ├── predictor_ui.py      # Prediction generator screen
│   ├── settings.py          # Settings screen + manual fetch button
│   └── statusbar.py         # Bottom status bar component
├── assets/
│   └── icon.png
├── exports/                 # Excel/CSV exports output folder
├── requirements.txt
└── CLAUDE.md                # This file

Database Schema

Table: games

Column Type Description
id INTEGER Primary key
name TEXT Game name (e.g. Powerball)
main_count INTEGER Number of main balls
main_max INTEGER Max value for main balls
bonus_count INTEGER Number of bonus balls (0 if none)
bonus_max INTEGER Max value for bonus ball
active INTEGER 1 = active, 0 = disabled

Table: draws

Column Type Description
id INTEGER Primary key
game_id INTEGER Foreign key → games.id
draw_date TEXT ISO date string (YYYY-MM-DD)
numbers TEXT Comma-separated main numbers
bonus TEXT Bonus ball number(s)
multiplier TEXT Power Play / Megaplier (nullable)
source TEXT Data source identifier
created_at TEXT Record insert timestamp

Table: predictions

Column Type Description
id INTEGER Primary key
game_id INTEGER Foreign key → games.id
strategy TEXT Strategy name used
numbers TEXT Predicted main numbers
bonus TEXT Predicted bonus number
created_at TEXT Prediction timestamp

Table: fetch_log

Column Type Description
id INTEGER Primary key
source TEXT Source name
fetched_at TEXT Timestamp of fetch
added INTEGER New records inserted
skipped INTEGER Duplicate records skipped
status TEXT success / error
message TEXT Error message or notes

Fetch System

Auto-Fetch

  • Triggers on app launch (background thread)
  • Repeats every 24 hours via APScheduler
  • Runs in background — does not block UI

Manual Fetch

  • Button in Toolbar (always visible, all screens)
  • Button in Settings screen
  • Shows "Fetching…" state while running

Duplicate Handling

  • Compare incoming records by draw_date + game_id
  • Skip if already exists in DB
  • Report result in status bar: X added, Y skipped

Status Bar Format

Last fetch: Powerball — 3 added, 2 skipped | Mega Millions — 5 added, 0 skipped | 2026-05-23 08:42 AM

Analysis Features

Feature Description
Frequency analysis Hot/cold numbers by total draw count
Gap/skip analysis How many draws since each number last appeared
Positional frequency Which numbers appear most in each draw position
Pair/triplet patterns Number combinations that appear together often
Odd/even ratio Ratio of odd vs even numbers per draw
Sum range analysis Distribution of total sums across all draws
Delta patterns Differences between consecutive numbers in a draw

Prediction Strategies

# Strategy Description
1 Hot Numbers Top N most frequent numbers in last X draws
2 Due Numbers Numbers overdue based on expected frequency gap
3 Weighted Random numpy random choice weighted by historical frequency
4 Monte Carlo 10,000 simulations, pick most common result
5 Positional Most frequent number per draw position

UI Screens

Screen Description
Dashboard Summary stats, last draw result, quick actions
History Searchable/sortable draw history table
Analysis Charts — frequency bar, heatmap, gap chart
Predictor Pick strategy → generate ticket numbers
Settings Game config, data sources, fetch interval, manual fetch

Logging

All actions are logged to console and optionally to a log file:

  • [FETCH] — auto/manual fetch events
  • [DB] — insert, skip, error events
  • [PREDICT] — prediction generated
  • [EXPORT] — export actions
  • [ERROR] — any exception with traceback

Build Phases & To-Do

Phase 0 — Planning

  • Define app scope and features
  • Choose tech stack
  • Design database schema
  • Design fetch system
  • Define data sources and API endpoints
  • Create CLAUDE.md

Phase 1 — Database Setup

  • Create lottosight/ project folder structure
  • Write db/database.py — SQLite init, create all tables
  • Write db/models.py — CRUD: insert draw, get draws, check duplicate, insert prediction, insert fetch log
  • Seed default game configs (Powerball, Mega Millions)
  • Write requirements.txt
  • Test DB creation and seed on fresh run
  • Write tests/conftest.py — shared tmp_db fixture
  • Write tests/test_database.py — 8 tests for database.py (47/47 pass)
  • Write tests/test_models.py — 39 tests for models.py (47/47 pass)
  • Write .gitea/workflows/ci.yml — CI on every push (syntax check + pytest)

Phase 2 — Fetch System

  • Write core/fetcher.py
    • fetch_powerball_ny() — NY Open Data API
    • fetch_megamillions_ny() — NY Open Data API
    • fetch_megamillions_tx() — Texas Lottery CSV
    • fetch_all() — calls all 3, aggregates results
    • Duplicate detection logic
    • Return added/skipped counts per source
  • Write ui/statusbar.py — bottom status bar widget
  • Wire auto-fetch on app launch (background thread)
  • Wire 24hr scheduled fetch (APScheduler)
  • Write main.py — app window, toolbar with manual fetch button
  • Wire manual fetch button → fetch_all() → update status bar
  • Test: fresh DB → fetch → verify records inserted (67/67 pass)
  • Test: second fetch → verify duplicates skipped, counts correct
  • Test: cross-source dedup (same date, different source → skipped)

Phase 3 — History Browser

  • Write ui/history.py
    • Treeview table with columns: Game, Date, Numbers, Bonus, Mult., Source
    • Filter by game (dropdown)
    • Search by date range (From / To entries)
    • Sort by column headers (▲/▼ indicators, numeric sort for bonus/multiplier)
    • Row count display
  • Connect history screen to DB reads via get_draws_with_game()
  • Auto-refresh after fetch completes
  • 13 tests (80/80 total passing)

Phase 4 — Analysis Engine + Charts

  • Write core/analyzer.py
    • frequency_analysis(game_id, last_n)
    • gap_analysis(game_id)
    • positional_frequency(game_id)
    • pair_analysis(game_id)
    • odd_even_ratio(game_id)
    • sum_range_analysis(game_id)
    • delta_analysis(game_id)
  • Write ui/analysis.py
    • Frequency bar chart (Matplotlib + FigureCanvasTkAgg)
    • Positional frequency heatmap (imshow, YlOrRd colormap)
    • Gap chart (color-coded: blue=recent, red=due)
    • Game dropdown + frequency window selector
    • NavigationToolbar on each tab for zoom/pan
  • 26 tests for all 7 analysis functions (106/106 total passing)

Phase 5 — Prediction Engine

  • Write core/predictor.py
    • hot_numbers(game_id, last_n=100) — top-frequency + most-frequent bonus
    • due_numbers(game_id) — highest gap numbers from pool
    • weighted_random(game_id) — numpy weighted choice (min weight 1 for unseen)
    • monte_carlo(game_id, simulations=10000) — tally-based selection
    • positional_pick(game_id) — per-position best with dedup
    • All strategies: random fallback on empty DB
  • Write ui/predictor_ui.py
    • Game + strategy + ticket count dropdowns
    • Generate button (disables during generation)
    • Treeview results: #, zero-padded numbers, bonus
    • Save to DB (insert_prediction per ticket) + Clear
    • Strategy description label
  • 18 tests — all 5 strategies × validity + empty DB + edge cases (124/124 total)

Phase 6 — Settings Screen

  • Write ui/settings.py
    • Game enable/disable checkboxes (set_game_active on toggle)
    • Fetch interval display (24 hours, read-only)
    • Manual fetch button (shared on_fetch callback from main.py)
    • Last fetch timestamp + added/skipped per source (colour-coded)
    • DB stats (draws per game + prediction count)
    • Scrollable canvas layout for future growth
  • Wire settings to DB reads/writes via main.py callback injection
  • 14 tests (138/138 total passing)

Phase 7 — Export + Polish

  • Write core/exporter.py
    • export_draws_excel(filepath, game_id, date_from, date_to) — openpyxl, styled header
    • export_draws_csv(filepath, game_id, date_from, date_to) — stdlib csv
    • export_predictions_excel(filepath, game_id) — openpyxl
    • export_predictions_csv(filepath, game_id) — stdlib csv
    • export_frequency_excel(filepath, game_id, last_n) — number + freq + gap
    • create_icon_png(path, size) — valid PNG, stdlib only (struct + zlib)
  • Add Export Excel + Export CSV buttons to History screen (filter-aware)
  • Add Export Excel + Export CSV buttons to Predictor screen (DB predictions)
  • Add Export Frequency button to Analysis screen (respects frequency window)
  • Auto-create assets/icon.png on startup if missing
  • Window min-size set (900×600) + resizable layout (all screens)
  • Error handling — try/except + messagebox.showerror on all export paths
  • 27 tests for exporter (165/165 total passing)

Phase 12 — Number Search + Next Draw Schedule

  • Number search in History screen
    • Add number param to get_draws_with_game() — SQL: ',' || numbers || ',' LIKE ? for exact boundary matching
    • Add "Number:" entry field to History filter bar; bound to <Return> for quick search
    • Wire through _apply_filter() and _clear_filter()
    • 7 new tests — exact match, boundary false-positive prevention, combined with game/date filter
  • Next draw schedule on Dashboard
    • _next_draw_date(game_name, from_date) — computes next Powerball (Mon/Wed/Sat) or Mega Millions (Tue/Fri) draw date
    • Shown on each Last Draw card as "Next draw: Sat, May 24" in green
    • 6 new tests — day-of-week transitions, unknown game, always-in-future guarantee
  • 227/227 tests passing

Phase 11 — Saved Predictions Viewer

  • Add delete_prediction(pred_id) and delete_all_predictions(game_id=None) to db/models.py
  • Refactor ui/predictor_ui.py to ttk.Notebook with two tabs
    • Generate tab — existing UI unchanged
    • Saved tab — treeview of all DB predictions (ID, Game, Strategy, Numbers, Bonus, Matches, Saved)
    • Match column — shows "X/5" comparing prediction vs last real draw (green if > 0, grey if zero)
    • Game filter dropdown — show all games or filter to one
    • Delete Selected — removes checked rows from DB + refreshes
    • Clear All — confirm dialog, then wipes all (or game-filtered) predictions
    • Auto-refreshes Saved tab after Save to DB
  • _count_matches() helper — set intersection between prediction and last draw numbers
  • tests/test_saved_predictions.py — 17 tests (214/214 total passing)

Phase 10 — Complete Analysis Screen (7 Charts)

  • Extend ui/analysis.py with 4 new chart tabs (was 3, now 7)
    • Pairs — horizontal bar chart, top-20 most common number pairs
    • Odd/Even — bar chart of draw-split distribution (e.g. 3O/2E = 38%)
    • Sum Range — histogram of total draw-sum distribution
    • Deltas — bar chart of gaps between consecutive numbers within draws
  • Add _draw_pairs, _draw_odd_even, _draw_sum_range, _draw_deltas pure functions
  • tests/test_analysis_charts.py — 23 tests using Agg backend (no display needed)
  • 200/200 total tests passing

Phase 9 — Dashboard Screen

  • Write ui/dashboard.py
    • Last Draw Results — card per active game (date, numbers, bonus, multiplier)
    • Database Summary — draw counts per game + prediction total
    • Hot Numbers — top-5 most-frequent per game (last 100 draws) with counts
    • Scrollable canvas layout (same pattern as Settings)
    • on_fetch callback injection for future toolbar wiring
  • Wire Dashboard into main.py — replaces "coming soon" placeholder; opens on launch
  • 12 tests (177/177 total passing)

Phase 8 — Packaging

  • Write core/paths.pyuser_data_dir() + bundled_asset() helpers (frozen-aware)
  • Update db/database.py + core/exporter.py to use user_data_dir() so DB + exports land next to the .exe when frozen
  • Update main.py to use bundled_asset() for icon lookup
  • Write lottosight.spec — directory build, no console, bundles assets/, matplotlib data, openpyxl templates, APScheduler hidden imports
  • Build verified: pyinstaller lottosight.spec --clean succeeds → dist/LottoSight/ (~115 MB)
  • assets/icon.png confirmed present in dist/LottoSight/_internal/assets/
  • Fix .gitignore — un-ignore *.spec, add data/*.db + exports/
  • 165/165 tests still passing after paths refactor
  • Test packaged app on a clean machine (no Python installed)

Notes

  • SQLite DB file stored at: lottosight/data/lottosight.db
  • Exports land in: lottosight/exports/
  • All fetch operations run in background threads to keep UI responsive
  • NY Open Data API supports $limit and $offset params for pagination
  • Texas Lottery CSV requires parsing — columns vary, needs header detection
  • Powerball matrix changed Oct 7, 2015 (5/69+1/26) — pre-2015 data has different pool sizes, flag in DB or filter