05/23 Phase 7

This commit is contained in:
2026-05-23 11:58:51 -04:00
parent c1405b5fb8
commit 8fc1878670
8 changed files with 638 additions and 15 deletions
+23 -1
View File
@@ -7,8 +7,9 @@ Analysis screen — three Matplotlib charts embedded in a ttk.Notebook.
• Gap — draws since each number last appeared
"""
import os
import tkinter as tk
from tkinter import ttk
from tkinter import ttk, filedialog, messagebox
import numpy as np
import matplotlib
@@ -18,6 +19,7 @@ from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolb
from db.models import get_all_games, get_game_by_id, get_game_by_name
from core.analyzer import frequency_analysis, gap_analysis, positional_frequency
from core.exporter import export_frequency_excel, ensure_exports_dir
_LAST_N_OPTIONS = {
"All draws": None,
@@ -60,6 +62,7 @@ class AnalysisScreen(ttk.Frame):
last_n_cb.bind("<<ComboboxSelected>>", lambda _: self._redraw_frequency())
ttk.Button(bar, text="↻ Refresh", command=self.refresh).pack(side="right")
ttk.Button(bar, text="Export Frequency", command=self._export_frequency).pack(side="right", padx=(0, 4))
# Notebook with three chart tabs
nb = ttk.Notebook(self)
@@ -141,6 +144,25 @@ class AnalysisScreen(ttk.Frame):
_draw_gap(ax, self._game_id)
self._gap_canvas.draw()
def _export_frequency(self):
if self._game_id is None:
messagebox.showinfo("Export", "Select a game first.")
return
ensure_exports_dir()
fp = filedialog.asksaveasfilename(
title="Export frequency analysis",
defaultextension=".xlsx",
filetypes=[("Excel workbook", "*.xlsx")],
initialfile=f"frequency_{__import__('datetime').datetime.now().strftime('%Y%m%d')}.xlsx",
)
if not fp:
return
try:
last_n = _LAST_N_OPTIONS.get(self._last_n_var.get())
export_frequency_excel(fp, self._game_id, last_n=last_n)
except Exception as e:
messagebox.showerror("Export failed", str(e))
# ── Pure chart-drawing functions (no Tkinter, just axes) ─────────────────────
+59 -2
View File
@@ -5,10 +5,14 @@ Draw History browser screen.
Shows a sortable, filterable Treeview of all draw records.
"""
import os
import tkinter as tk
from tkinter import ttk
from tkinter import ttk, filedialog, messagebox
from db.models import get_all_games, get_game_by_name, get_draws_with_game
from core.exporter import (
export_draws_excel, export_draws_csv, default_path, ensure_exports_dir,
)
_COLUMNS = ("game", "date", "numbers", "bonus", "multiplier", "source")
_LABELS = {
@@ -77,7 +81,9 @@ class HistoryScreen(ttk.Frame):
ttk.Button(bar, text="Search", command=self._apply_filter).pack(side="left", padx=(0, 4))
ttk.Button(bar, text="Clear", command=self._clear_filter).pack(side="left")
ttk.Button(bar, text="↻ Refresh", command=self.refresh).pack(side="right")
ttk.Button(bar, text="↻ Refresh", command=self.refresh).pack(side="right")
ttk.Button(bar, text="Export CSV", command=self._export_csv).pack(side="right", padx=(0, 4))
ttk.Button(bar, text="Export Excel",command=self._export_excel).pack(side="right", padx=(0, 4))
# ── Treeview + scrollbars ─────────────────────────────────────────────
tree_frame = ttk.Frame(self)
@@ -213,3 +219,54 @@ class HistoryScreen(ttk.Frame):
for c in _COLUMNS:
self._tree.heading(c, text=_LABELS[c])
self._apply_filter()
# ── Export ────────────────────────────────────────────────────────────────
def _current_filter(self):
"""Return (game_id, date_from, date_to) for the active filter."""
name = self._game_var.get()
if name == "All Games":
game_id = None
else:
g = get_game_by_name(name)
game_id = g["id"] if g else None
raw_from = self._from_entry.get().strip()
raw_to = self._to_entry.get().strip()
date_from = raw_from if raw_from and raw_from != "YYYY-MM-DD" else None
date_to = raw_to if raw_to and raw_to != "YYYY-MM-DD" else None
return game_id, date_from, date_to
def _export_excel(self):
ensure_exports_dir()
fp = filedialog.asksaveasfilename(
title="Export draw history",
defaultextension=".xlsx",
filetypes=[("Excel workbook", "*.xlsx")],
initialfile=f"draws_{__import__('datetime').datetime.now().strftime('%Y%m%d')}.xlsx",
)
if not fp:
return
try:
game_id, date_from, date_to = self._current_filter()
export_draws_excel(fp, game_id=game_id, date_from=date_from, date_to=date_to)
self._count_var.set(f"Exported → {os.path.basename(fp)}")
except Exception as e:
messagebox.showerror("Export failed", str(e))
def _export_csv(self):
ensure_exports_dir()
fp = filedialog.asksaveasfilename(
title="Export draw history",
defaultextension=".csv",
filetypes=[("CSV file", "*.csv")],
initialfile=f"draws_{__import__('datetime').datetime.now().strftime('%Y%m%d')}.csv",
)
if not fp:
return
try:
game_id, date_from, date_to = self._current_filter()
export_draws_csv(fp, game_id=game_id, date_from=date_from, date_to=date_to)
self._count_var.set(f"Exported → {os.path.basename(fp)}")
except Exception as e:
messagebox.showerror("Export failed", str(e))
+45 -1
View File
@@ -5,14 +5,16 @@ Prediction generator screen.
Pick a strategy + game + ticket count → generate → save to DB.
"""
import os
import tkinter as tk
from tkinter import ttk
from tkinter import ttk, filedialog, messagebox
import logging
from db.models import get_all_games, get_game_by_name, insert_prediction
from core.predictor import (
hot_numbers, due_numbers, weighted_random, monte_carlo, positional_pick,
)
from core.exporter import export_predictions_excel, export_predictions_csv, ensure_exports_dir
logger = logging.getLogger(__name__)
@@ -121,6 +123,14 @@ class PredictorScreen(ttk.Frame):
bottom, text="Clear", command=self._clear
).pack(side="right", padx=(0, 4))
ttk.Button(
bottom, text="Export CSV", command=self._export_csv, state="normal"
).pack(side="right", padx=(0, 4))
ttk.Button(
bottom, text="Export Excel", command=self._export_excel, state="normal"
).pack(side="right", padx=(0, 4))
# ── Callbacks ─────────────────────────────────────────────────────────────
def refresh(self):
@@ -198,3 +208,37 @@ class PredictorScreen(ttk.Frame):
self._tree.delete(*self._tree.get_children())
self._save_btn.config(state="disabled")
self._status_var.set("")
def _export_excel(self):
ensure_exports_dir()
fp = filedialog.asksaveasfilename(
title="Export predictions",
defaultextension=".xlsx",
filetypes=[("Excel workbook", "*.xlsx")],
initialfile=f"predictions_{__import__('datetime').datetime.now().strftime('%Y%m%d')}.xlsx",
)
if not fp:
return
try:
game_id = self._game_id
export_predictions_excel(fp, game_id=game_id)
self._status_var.set(f"Exported → {os.path.basename(fp)}")
except Exception as e:
messagebox.showerror("Export failed", str(e))
def _export_csv(self):
ensure_exports_dir()
fp = filedialog.asksaveasfilename(
title="Export predictions",
defaultextension=".csv",
filetypes=[("CSV file", "*.csv")],
initialfile=f"predictions_{__import__('datetime').datetime.now().strftime('%Y%m%d')}.csv",
)
if not fp:
return
try:
game_id = self._game_id
export_predictions_csv(fp, game_id=game_id)
self._status_var.set(f"Exported → {os.path.basename(fp)}")
except Exception as e:
messagebox.showerror("Export failed", str(e))