Files
lottosight/CLAUDE.md
T
2026-05-23 11:01:40 -04:00

334 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
- [x] Define app scope and features
- [x] Choose tech stack
- [x] Design database schema
- [x] Design fetch system
- [x] Define data sources and API endpoints
- [x] Create CLAUDE.md
---
### ✅ Phase 1 — Database Setup
- [x] Create `lottosight/` project folder structure
- [x] Write `db/database.py` — SQLite init, create all tables
- [x] Write `db/models.py` — CRUD: insert draw, get draws, check duplicate, insert prediction, insert fetch log
- [x] Seed default game configs (Powerball, Mega Millions)
- [x] Write `requirements.txt`
- [x] Test DB creation and seed on fresh run
- [x] Write `tests/conftest.py` — shared tmp_db fixture
- [x] Write `tests/test_database.py` — 8 tests for database.py (47/47 pass)
- [x] Write `tests/test_models.py` — 39 tests for models.py (47/47 pass)
- [x] Write `.gitea/workflows/ci.yml` — CI on every push (syntax check + pytest)
---
### ✅ Phase 2 — Fetch System
- [x] Write `core/fetcher.py`
- [x] `fetch_powerball_ny()` — NY Open Data API
- [x] `fetch_megamillions_ny()` — NY Open Data API
- [x] `fetch_megamillions_tx()` — Texas Lottery CSV
- [x] `fetch_all()` — calls all 3, aggregates results
- [x] Duplicate detection logic
- [x] Return added/skipped counts per source
- [x] Write `ui/statusbar.py` — bottom status bar widget
- [x] Wire auto-fetch on app launch (background thread)
- [x] Wire 24hr scheduled fetch (APScheduler)
- [x] Write `main.py` — app window, toolbar with manual fetch button
- [x] Wire manual fetch button → `fetch_all()` → update status bar
- [x] Test: fresh DB → fetch → verify records inserted (67/67 pass)
- [x] Test: second fetch → verify duplicates skipped, counts correct
- [x] Test: cross-source dedup (same date, different source → skipped)
---
### 🔲 Phase 3 — History Browser
- [ ] Write `ui/history.py`
- [ ] Treeview table with columns: Date, Numbers, Bonus, Multiplier, Source
- [ ] Filter by game (dropdown)
- [ ] Search by date range
- [ ] Sort by column headers
- [ ] Row count display
- [ ] Connect history screen to DB reads
- [ ] Test with real fetched data
---
### 🔲 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 embedded)
- [ ] Heatmap of number frequency
- [ ] Gap chart
- [ ] Toggle between games
- [ ] Test all analysis functions with real data
---
### 🔲 Phase 5 — Prediction Engine
- [ ] Write `core/predictor.py`
- [ ] `hot_numbers(game_id, last_n)`
- [ ] `due_numbers(game_id)`
- [ ] `weighted_random(game_id)`
- [ ] `monte_carlo(game_id, simulations=10000)`
- [ ] `positional_pick(game_id)`
- [ ] Write `ui/predictor_ui.py`
- [ ] Strategy selector dropdown
- [ ] Number of tickets input
- [ ] Generate button
- [ ] Results display (generated tickets)
- [ ] Save prediction to DB
- [ ] Test all 5 strategies produce valid number sets
---
### 🔲 Phase 6 — Settings Screen
- [ ] Write `ui/settings.py`
- [ ] Game enable/disable toggles
- [ ] Fetch interval display (24hrs, read-only for now)
- [ ] Manual fetch button (same as toolbar)
- [ ] Last fetch timestamp per source
- [ ] DB stats (total records per game)
- [ ] Wire settings to DB config reads/writes
---
### 🔲 Phase 7 — Export + Polish
- [ ] Add export to Excel (`openpyxl`) for:
- [ ] Draw history
- [ ] Predictions
- [ ] Frequency analysis
- [ ] Add export to CSV
- [ ] Add `assets/icon.png`
- [ ] App title bar + icon
- [ ] Window min-size + resizable layout
- [ ] Error handling — network down, API timeout, bad CSV
---
### 🔲 Phase 8 — Packaging
- [ ] Write PyInstaller `.spec` file
- [ ] Test build on target OS (Windows / Mac / Linux)
- [ ] Bundle SQLite DB, assets, exports folder
- [ ] Test packaged app fresh install (no Python required)
---
## 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