Initial commit: Eurojackpot analysis and prediction system

This repository contains a comprehensive Eurojackpot lottery analysis and prediction system including:
- Historical data analysis and processing
- ML-based prediction models
- Automated weekly tip generation
- Position and range analysis tools
- Notification system for results

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
cbazzaandClaude Sonnet 4.5 committed 2025-12-16 15:53:01 +01:00
commit 70e0638dee
67 files changed
+8491869

No files matched your search

+358
View File
@@ -0,0 +1,358 @@
# Eurojackpot Automation System
Vollautomatisches System für wöchentliche Tipp-Generierung und Learning nach Ziehungen.
## 📋 Überblick
Das System besteht aus 2 Hauptkomponenten:
1. **Weekly Tip Generator** - Generiert automatisch Tipps vor Ziehungen
2. **Auto Update & Learn** - Aktualisiert Daten und lernt nach Ziehungen
## 🚀 Installation
### 1. Virtuelle Umgebung aktivieren
```bash
cd "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot"
source venv/bin/activate
```
### 2. Scripts ausführbar machen
```bash
chmod +x scripts/automation/*.py
```
## 🎯 Manuelle Nutzung
### Tipps generieren
```bash
# Normale Generierung (prüft ob nötig)
python scripts/automation/weekly_tip_generator.py
# Erzwinge Generierung
python scripts/automation/weekly_tip_generator.py --force
# Generiere 20 Tipps statt 10
python scripts/automation/weekly_tip_generator.py --num-tips 20
# Zeige nur Historie
python scripts/automation/weekly_tip_generator.py --history
```
### Nach Ziehung aktualisieren
```bash
# Kompletter Workflow: Update + Evaluation + Learning
python scripts/automation/auto_update_and_learn.py
```
## ⏰ Automatisierung mit Cron
### Setup
1. Öffne Crontab:
```bash
crontab -e
```
2. Füge folgende Zeilen hinzu:
```bash
# Pfad zur virtuellen Umgebung
EUROJACKPOT_PATH="/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot"
# Montag & Donnerstag 09:00 Uhr: Tipps generieren (vor Ziehung)
0 9 * * 1,4 cd "$EUROJACKPOT_PATH" && source venv/bin/activate && python scripts/automation/weekly_tip_generator.py >> logs/tips_generation.log 2>&1
# Dienstag & Freitag 21:00 Uhr: Update nach Ziehung
0 21 * * 2,5 cd "$EUROJACKPOT_PATH" && source venv/bin/activate && python scripts/automation/auto_update_and_learn.py >> logs/auto_update.log 2>&1
```
3. Speichern (ESC, :wq in vim)
### Cron Zeitplan
```
Montag 09:00 → Tipps für Dienstag-Ziehung generieren
Dienstag 20:00 → Ziehung findet statt
Dienstag 21:00 → Auto-Update & Learning
Donnerstag 09:00 → Tipps für Freitag-Ziehung generieren
Freitag 20:00 → Ziehung findet statt
Freitag 21:00 → Auto-Update & Learning
```
### Logs prüfen
```bash
# Erstelle Log-Verzeichnis
mkdir -p logs
# Zeige letzte Tipps-Generierung
tail -50 logs/tips_generation.log
# Zeige letzte Updates
tail -50 logs/auto_update.log
```
## 📊 Dateien & Verzeichnisse
```
data/
├── generated_tips/ # Generierte Tipps
│ ├── weekly_tips_*.csv # Tipp-Dateien
│ └── generation_history.json # Historie
│
├── performance_reports/ # Performance-Reports
│ └── report_*.txt # Reports nach Ziehungen
│
├── learning_log.json # Learning-Historie
└── backups/ # Automatische Backups
logs/
├── tips_generation.log # Cron Log für Generierung
└── auto_update.log # Cron Log für Updates
```
## 🔍 Features im Detail
### Weekly Tip Generator
**Intelligente Prüfung:**
- Generiert nur wenn nötig (> 3 Tage seit letzter Generierung)
- Berücksichtigt Wochentage (Montag/Donnerstag vor Ziehungen)
- Vermeidet unnötige Generierungen
**Historie-Tracking:**
- Speichert alle Generierungen
- Trackt Confidence & Quality Scores
- Ermöglicht Performance-Analyse über Zeit
**Ausgabe:**
```
📊 GENERIERUNGS-HISTORIE
======================================================================
Nr Datum Tips Confidence Quality Datei
----------------------------------------------------------------------
1 2025-01-20 09:00 10 0.5823 0.6734 weekly_tips_20250120_090000.csv
2 2025-01-16 09:00 10 0.5891 0.6812 weekly_tips_20250116_090000.csv
```
### Auto Update & Learn
**4-Schritt-Workflow:**
1. **Daten aktualisieren**
- Lädt neueste Ziehung von API
- Erstellt automatisches Backup
- Validiert Daten
2. **Neue Ziehung prüfen**
- Erkennt automatisch neue Ziehungen
- Verhindert Doppel-Verarbeitung
- Extrahiert Ziehungsdaten
3. **Tipps evaluieren**
- Vergleicht letzte Tipps mit Ziehung
- Zählt Treffer (Main + Euro)
- Ermittelt beste Strategien
4. **Learning Update**
- Passt ML-Modelle an
- Aktualisiert Predictions
- Speichert Performance-Metriken
**Evaluation Output:**
```
🎯 EVALUIERE LETZTE TIPPS
======================================================================
Tip Strategie Main Euro Gesamt Bewertung
------------------------------------------------------------
#1 PURE-AI 2 1 3 ✅ Gut
#2 HYBRID-OPT 3 0 3 ✅ Gut
#3 PURE-PATTERN 1 1 2 👍 OK
...
🏆 Bester Tipp: #2 (3 Main + 0 Euro)
```
## 📈 Performance-Reports
Reports werden automatisch nach jeder Ziehung erstellt:
```
======================================================================
EUROJACKPOT PERFORMANCE REPORT
======================================================================
Erstellt: 2025-01-17 21:05:23
ZIEHUNG VOM 2025-01-17
----------------------------------------------------------------------
Hauptzahlen: [3, 9, 12, 24, 39]
Eurozahlen: [5, 10]
EVALUATION DER TIPPS
----------------------------------------------------------------------
Datei: weekly_tips_20250115_090000.csv
Tipps evaluiert: 10
Avg Main Matches: 1.80
Avg Euro Matches: 0.60
Bester Tipp: #5
- Main Treffer: 3
- Euro Treffer: 1
======================================================================
```
## 🛠️ Troubleshooting
### "No module named 'requests'"
```bash
cd "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot"
source venv/bin/activate
pip install requests beautifulsoup4 pandas numpy scikit-learn
```
### "Permission denied"
```bash
chmod +x scripts/automation/*.py
```
### Cron läuft nicht
```bash
# Prüfe Cron-Service
launchctl list | grep cron
# Prüfe System-Logs
tail -f /var/log/system.log | grep cron
# Test manuell
cd "/path/to/eurojackpot"
source venv/bin/activate
python scripts/automation/weekly_tip_generator.py
```
### Logs sind leer
Stelle sicher dass das logs-Verzeichnis existiert:
```bash
mkdir -p logs
```
## 🎯 Best Practices
### 1. Teste manuell vor Cron
```bash
# Test 1: Tipps generieren
python scripts/automation/weekly_tip_generator.py --force
# Test 2: Update & Learn
python scripts/automation/auto_update_and_learn.py
```
### 2. Überwache Logs regelmäßig
```bash
# Wöchentlich prüfen
tail -100 logs/tips_generation.log
tail -100 logs/auto_update.log
```
### 3. Backup-Strategie
Backups werden automatisch erstellt, aber zusätzlich:
```bash
# Manuelles Backup
cp AlleEurojackpotzahlen.csv "AlleEurojackpotzahlen_$(date +%Y%m%d).csv"
```
### 4. Performance-Analyse
```bash
# Zeige Generierungs-Historie
python scripts/automation/weekly_tip_generator.py --history
# Analysiere Reports
cat data/performance_reports/report_*.txt | grep "Avg Main Matches"
```
## 📱 Benachrichtigungen (Optional)
Füge Benachrichtigungen zu Cron hinzu:
### macOS Notification
```bash
# In Cron-Zeile hinzufügen:
&& osascript -e 'display notification "Eurojackpot Tipps generiert" with title "Automation"'
```
### Email (wenn konfiguriert)
```bash
# In Cron-Zeile:
&& echo "Tipps generiert" | mail -s "Eurojackpot Update" your@email.com
```
## 🔄 Workflow-Diagramm
```
WOCHE
│
├─ Montag 09:00
│ └─ 🎲 Generiere Tipps für Dienstag
│ └─ weekly_tips_TIMESTAMP.csv
│
├─ Dienstag 20:00
│ └─ 🎰 Ziehung findet statt
│
├─ Dienstag 21:00
│ └─ 🔄 Auto-Update & Learning
│ ├─ Daten aktualisieren
│ ├─ Tipps evaluieren
│ ├─ Learning Update
│ └─ Report erstellen
│
├─ Donnerstag 09:00
│ └─ 🎲 Generiere Tipps für Freitag
│ └─ weekly_tips_TIMESTAMP.csv
│
├─ Freitag 20:00
│ └─ 🎰 Ziehung findet statt
│
└─ Freitag 21:00
└─ 🔄 Auto-Update & Learning
├─ Daten aktualisieren
├─ Tipps evaluieren
├─ Learning Update
└─ Report erstellen
```
## 💡 Tipps
1. **Erste Woche:** Nutze `--force` um initiale Tipps zu generieren
2. **Strategie-Mix:** Das System nutzt automatisch den optimalen Mix
3. **Learning:** Nach 4-5 Ziehungen beginnt das System besser zu werden
4. **Reports:** Analysiere Reports monatlich für Trend-Analyse
5. **Backup:** Die automatischen Backups werden im backups/ Ordner gespeichert
## 🆘 Support
Bei Problemen:
1. Prüfe Logs: `tail -100 logs/*.log`
2. Teste manuell: `python script.py`
3. Prüfe venv: `source venv/bin/activate && pip list`
4. Checke Cronjobs: `crontab -l`
---
**Version:** 1.0
**Erstellt:** 2025-01-25
**Kompatibel mit:** Ultimate AI-ML Generator V2.1
+445
View File
@@ -0,0 +1,445 @@
#!/usr/bin/env python3
"""
Automatischer Eurojackpot Update & Learning Workflow
Nach jeder Ziehung:
1. Aktualisiert Daten von API
2. Evaluiert letzte generierte Tipps
3. Real-Time Learning Update
4. Performance-Report
Verwendung:
python auto_update_and_learn.py
Oder als Cronjob (nach Ziehung):
0 21 * * 2,5 cd /path/to/eurojackpot && source venv/bin/activate && python scripts/automation/auto_update_and_learn.py
"""
import sys
import os
from datetime import datetime, timedelta
import json
import pandas as pd
# Path Setup
script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(os.path.dirname(script_dir))
sys.path.insert(0, project_dir)
from scripts.utils.update_from_api import EurojackpotAPIUpdater
from scripts.generators.ultimate_ai_ml_eurojackpot_generator import UltimateAIMLEurojackpotGenerator
from scripts.utils.notifier import EurojackpotNotifier
class AutoUpdateAndLearn:
"""Automatisches Update und Learning System."""
def __init__(self, data_dir: str):
self.data_dir = data_dir
# CSV file is in Eurojackpot/data folder
# data_dir = .../Eurojackpot/data
# We need .../Eurojackpot/data/AlleEurojackpotzahlen.csv
self.data_file = os.path.join(data_dir, "AlleEurojackpotzahlen.csv")
self.tips_dir = os.path.join(data_dir, "generated_tips")
self.reports_dir = os.path.join(data_dir, "performance_reports")
self.learning_log = os.path.join(data_dir, "learning_log.json")
os.makedirs(self.reports_dir, exist_ok=True)
# Initialisiere Notifier
self.notifier = EurojackpotNotifier()
print("🤖 AUTOMATISCHES UPDATE & LEARNING SYSTEM")
print("=" * 70)
def load_learning_log(self) -> dict:
"""Lädt Learning Log."""
if os.path.exists(self.learning_log):
with open(self.learning_log, 'r') as f:
return json.load(f)
return {"updates": []}
def save_learning_log(self, log: dict):
"""Speichert Learning Log."""
with open(self.learning_log, 'w') as f:
json.dump(log, f, indent=2)
def check_for_new_draw(self) -> dict:
"""
Prüft ob neue Ziehung verfügbar ist.
Returns:
Dict mit neuer Ziehung oder None
"""
print("\n🔍 PRÜFE AUF NEUE ZIEHUNG")
print("=" * 70)
log = self.load_learning_log()
# Lade aktuelle Daten
try:
df = pd.read_csv(self.data_file, sep=';')
df['datum'] = pd.to_datetime(df['datum'], format='%Y-%m-%d')
latest_draw = df.iloc[0] # Neueste Ziehung (sortiert absteigend)
latest_date = latest_draw['datum']
print(f" 📅 Neueste Ziehung in Daten: {latest_date.strftime('%Y-%m-%d')}")
# Prüfe ob schon verarbeitet
if log["updates"]:
last_processed = log["updates"][-1].get("draw_date")
if last_processed == latest_date.strftime('%Y-%m-%d'):
print(f" ⏭️ Bereits verarbeitet")
return None
print(f" ✅ Neue Ziehung gefunden!")
return {
'date': latest_date,
'Z1': int(latest_draw['Z1']),
'Z2': int(latest_draw['Z2']),
'Z3': int(latest_draw['Z3']),
'Z4': int(latest_draw['Z4']),
'Z5': int(latest_draw['Z5']),
'SZ1': int(latest_draw['SZ1']),
'SZ2': int(latest_draw['SZ2'])
}
except Exception as e:
print(f" ❌ Fehler beim Prüfen: {e}")
return None
def update_data(self) -> bool:
"""
Aktualisiert Daten von API.
Returns:
True bei Erfolg
"""
print("\n📥 AKTUALISIERE DATEN VON API")
print("=" * 70)
try:
updater = EurojackpotAPIUpdater(self.data_file)
success = updater.update(api_name='all', create_backup=True)
if success:
print(" ✅ Daten erfolgreich aktualisiert")
else:
print(" ⚠️ Update ohne neue Daten")
return success
except Exception as e:
print(f" ❌ Fehler beim Update: {e}")
return False
def evaluate_tips(self, new_draw: dict) -> dict:
"""
Evaluiert letzte generierte Tipps gegen neue Ziehung.
Args:
new_draw: Dict mit neuer Ziehung
Returns:
Evaluierungs-Ergebnisse
"""
print("\n🎯 EVALUIERE LETZTE TIPPS")
print("=" * 70)
# Finde neueste Tipps-Datei
if not os.path.exists(self.tips_dir):
print(" ⚠️ Keine Tipps zum Evaluieren")
return {}
tip_files = sorted(
[f for f in os.listdir(self.tips_dir) if f.endswith('.csv')],
reverse=True
)
if not tip_files:
print(" ⚠️ Keine Tipps-Dateien gefunden")
return {}
latest_tips_file = os.path.join(self.tips_dir, tip_files[0])
print(f" 📁 Evaluiere: {tip_files[0]}")
try:
tips_df = pd.read_csv(latest_tips_file)
# Extrahiere gezogene Zahlen
drawn_main = [new_draw[f'Z{i}'] for i in range(1, 6)]
drawn_euro = [new_draw['SZ1'], new_draw['SZ2']]
print(f" 🎲 Gezogene Zahlen: {drawn_main} + Euro {drawn_euro}")
print()
results = []
best_matches = {'main': 0, 'euro': 0, 'tip': None}
for _, tip in tips_df.iterrows():
# Parse Hauptzahlen
main_str = tip['Main_Numbers']
# Handle both formats: "[1, 2, 3]" and "1-2-3"
if main_str.startswith('['):
# Parse Python list format
import ast
tip_main = ast.literal_eval(main_str)
else:
# Parse dash-separated format
tip_main = [int(n) for n in main_str.split('-')]
# Parse Eurozahlen
euro_str = tip['Euro_Numbers']
if euro_str.startswith('['):
import ast
tip_euro = ast.literal_eval(euro_str)
else:
tip_euro = [int(n) for n in euro_str.split('-')]
# Zähle Treffer
main_matches = len(set(tip_main) & set(drawn_main))
euro_matches = len(set(tip_euro) & set(drawn_euro))
total_matches = main_matches + euro_matches
results.append({
'tip_number': tip['Tip_Number'],
'strategy': tip['Strategy'],
'main_matches': main_matches,
'euro_matches': euro_matches,
'total_matches': total_matches
})
# Track best
if total_matches > (best_matches['main'] + best_matches['euro']):
best_matches = {
'main': main_matches,
'euro': euro_matches,
'tip': tip['Tip_Number']
}
# Ausgabe
print(f" {'Tip':<5} {'Strategie':<15} {'Main':<6} {'Euro':<6} {'Gesamt':<8} {'Bewertung'}")
print(" " + "-" * 60)
for r in results:
rating = self._get_match_rating(r['main_matches'], r['euro_matches'])
print(f" #{r['tip_number']:<4} {r['strategy']:<15} "
f"{r['main_matches']:<6} {r['euro_matches']:<6} "
f"{r['total_matches']:<8} {rating}")
print()
print(f" 🏆 Bester Tipp: #{best_matches['tip']} "
f"({best_matches['main']} Main + {best_matches['euro']} Euro)")
return {
'file': tip_files[0],
'results': results,
'best': best_matches,
'avg_main_matches': sum(r['main_matches'] for r in results) / len(results),
'avg_euro_matches': sum(r['euro_matches'] for r in results) / len(results)
}
except Exception as e:
print(f" ❌ Fehler bei Evaluation: {e}")
import traceback
traceback.print_exc()
return {}
def _get_match_rating(self, main: int, euro: int) -> str:
"""Bewertung der Treffer."""
total = main + euro
if main == 5 and euro == 2:
return "🏆 JACKPOT!"
elif main == 5 and euro == 1:
return "💰 Klasse 2"
elif main == 5 and euro == 0:
return "💰 Klasse 3"
elif main == 4 and euro == 2:
return "💰 Klasse 4"
elif main == 4 and euro == 1:
return "💵 Klasse 5"
elif total >= 3:
return "✅ Gut"
elif total >= 2:
return "👍 OK"
else:
return "⚪ Niedrig"
def perform_learning_update(self, new_draw: dict) -> bool:
"""
Führt Real-Time Learning Update durch.
Args:
new_draw: Dict mit neuer Ziehung
Returns:
True bei Erfolg
"""
print("\n🧠 REAL-TIME LEARNING UPDATE")
print("=" * 70)
try:
# Initialisiere Generator
generator = UltimateAIMLEurojackpotGenerator(
self.data_file,
fast_mode=True
)
# Learning Update
generator.real_time_learner.learn_from_result(new_draw)
# Performance Tracking
generator.performance_tracker.evaluate_predictions(new_draw)
print(" ✅ Learning Update durchgeführt")
print(" 📊 Models wurden angepasst")
return True
except Exception as e:
print(f" ❌ Fehler beim Learning: {e}")
return False
def generate_report(self, new_draw: dict, evaluation: dict):
"""Generiert Performance-Report."""
print("\n📊 PERFORMANCE-REPORT")
print("=" * 70)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
report_file = os.path.join(
self.reports_dir,
f"report_{timestamp}.txt"
)
report = []
report.append("=" * 70)
report.append("EUROJACKPOT PERFORMANCE REPORT")
report.append("=" * 70)
report.append(f"Erstellt: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
report.append("")
report.append(f"ZIEHUNG VOM {new_draw['date'].strftime('%Y-%m-%d')}")
report.append("-" * 70)
report.append(f"Hauptzahlen: {[new_draw[f'Z{i}'] for i in range(1, 6)]}")
report.append(f"Eurozahlen: [{new_draw['SZ1']}, {new_draw['SZ2']}]")
report.append("")
if evaluation:
report.append("EVALUATION DER TIPPS")
report.append("-" * 70)
report.append(f"Datei: {evaluation['file']}")
report.append(f"Tipps evaluiert: {len(evaluation['results'])}")
report.append(f"Avg Main Matches: {evaluation['avg_main_matches']:.2f}")
report.append(f"Avg Euro Matches: {evaluation['avg_euro_matches']:.2f}")
report.append(f"Bester Tipp: #{evaluation['best']['tip']}")
report.append(f" - Main Treffer: {evaluation['best']['main']}")
report.append(f" - Euro Treffer: {evaluation['best']['euro']}")
report.append("")
report.append("=" * 70)
# Speichern
with open(report_file, 'w') as f:
f.write('\n'.join(report))
# Ausgabe
for line in report:
print(line)
print(f"\n📁 Report gespeichert: {os.path.basename(report_file)}")
def run(self):
"""Führt kompletten Workflow aus."""
print()
print("=" * 70)
print("START: AUTOMATISCHER UPDATE & LEARNING WORKFLOW")
print("=" * 70)
# 1. Update Daten
print("\n[SCHRITT 1/4] Daten aktualisieren")
self.update_data()
# 2. Prüfe auf neue Ziehung
print("\n[SCHRITT 2/4] Neue Ziehung prüfen")
new_draw = self.check_for_new_draw()
if not new_draw:
print("\n⏭️ Keine neue Ziehung - Workflow beendet")
return True
# 3. Evaluiere Tipps
print("\n[SCHRITT 3/4] Tipps evaluieren")
evaluation = self.evaluate_tips(new_draw)
# 4. Learning Update
print("\n[SCHRITT 4/4] Learning Update")
self.perform_learning_update(new_draw)
# Report
self.generate_report(new_draw, evaluation)
# Log Update
log = self.load_learning_log()
log["updates"].append({
"timestamp": datetime.now().isoformat(),
"draw_date": new_draw['date'].strftime('%Y-%m-%d'),
"evaluation": evaluation.get('best', {}),
"avg_matches": {
'main': evaluation.get('avg_main_matches', 0),
'euro': evaluation.get('avg_euro_matches', 0)
}
})
self.save_learning_log(log)
# Sende Benachrichtigung
try:
best_match = {
'main_matches': evaluation.get('best', {}).get('main', 0),
'euro_matches': evaluation.get('best', {}).get('euro', 0)
}
evaluation_summary = {
'avg_main': evaluation.get('avg_main_matches', 0),
'avg_euro': evaluation.get('avg_euro_matches', 0)
}
self.notifier.send_draw_results(new_draw, evaluation_summary, best_match)
except Exception as e:
print(f"⚠️ Benachrichtigung fehlgeschlagen: {e}")
print("\n" + "=" * 70)
print("✅ WORKFLOW ERFOLGREICH ABGESCHLOSSEN")
print("=" * 70)
return True
def main():
"""Hauptfunktion."""
import argparse
parser = argparse.ArgumentParser(
description="Automatisches Update & Learning nach Ziehung"
)
parser.add_argument(
'--data-dir',
type=str,
default="/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data",
help='Daten-Verzeichnis'
)
args = parser.parse_args()
# Run Workflow
workflow = AutoUpdateAndLearn(args.data_dir)
success = workflow.run()
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()
+278
View File
@@ -0,0 +1,278 @@
#!/usr/bin/env python3
"""
Wöchentlicher Eurojackpot Tipp-Generator
Automatisiert:
1. Prüft ob neue Tipps nötig sind (basierend auf letzter Generierung)
2. Generiert 10 Ultimate Tipps
3. Speichert mit Timestamp
4. Trackt Generierungs-Historie
Verwendung:
python weekly_tip_generator.py
Oder als Cronjob:
0 9 * * 2,5 cd /path/to/eurojackpot && source venv/bin/activate && python scripts/automation/weekly_tip_generator.py
"""
import sys
import os
from datetime import datetime, timedelta
import json
# Füge Parent-Verzeichnisse zum Path hinzu
script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(os.path.dirname(script_dir))
generators_dir = os.path.join(project_dir, 'scripts', 'generators')
sys.path.insert(0, project_dir)
sys.path.insert(0, generators_dir)
# Import des Ultimate Generators
from scripts.generators.ultimate_ai_ml_eurojackpot_generator import UltimateAIMLEurojackpotGenerator
from scripts.utils.notifier import EurojackpotNotifier
class WeeklyTipGenerator:
"""Automatischer wöchentlicher Tipp-Generator."""
def __init__(self, data_dir: str):
self.data_dir = data_dir
# CSV file is in Eurojackpot/data folder
# data_dir = .../Eurojackpot/data
# We need .../Eurojackpot/data/AlleEurojackpotzahlen.csv
self.data_file = os.path.join(data_dir, "AlleEurojackpotzahlen.csv")
self.tips_dir = os.path.join(data_dir, "generated_tips")
self.history_file = os.path.join(self.tips_dir, "generation_history.json")
os.makedirs(self.tips_dir, exist_ok=True)
# Initialisiere Notifier
self.notifier = EurojackpotNotifier()
print("🤖 AUTOMATISCHER WÖCHENTLICHER TIPP-GENERATOR")
print("=" * 70)
def load_history(self) -> dict:
"""Lädt Generierungs-Historie."""
if os.path.exists(self.history_file):
with open(self.history_file, 'r') as f:
return json.load(f)
return {"generations": []}
def save_history(self, history: dict):
"""Speichert Historie."""
with open(self.history_file, 'w') as f:
json.dump(history, f, indent=2)
def needs_new_tips(self) -> bool:
"""
Prüft ob neue Tipps nötig sind.
Logik:
- Eurojackpot: Dienstag & Freitag Ziehungen
- Generiere Tipps wenn:
a) Noch nie generiert
b) Letzte Generierung > 3 Tage her
c) Es ist Montag oder Donnerstag (vor Ziehung)
"""
history = self.load_history()
if not history["generations"]:
print(" ℹ️ Noch nie Tipps generiert")
return True
last_gen = history["generations"][-1]
last_date = datetime.fromisoformat(last_gen["timestamp"])
days_since = (datetime.now() - last_date).days
print(f" 📅 Letzte Generierung: {last_date.strftime('%Y-%m-%d %H:%M')}")
print(f" ⏱️ Vor {days_since} Tagen")
# Wenn > 3 Tage her
if days_since > 3:
print(" ✅ Mehr als 3 Tage her - neue Tipps nötig")
return True
# Prüfe Wochentag (0=Montag, 4=Freitag)
today = datetime.now().weekday()
# Montag (vor Dienstag-Ziehung)
if today == 0 and days_since >= 1:
print(" ✅ Montag - generiere für Dienstag-Ziehung")
return True
# Donnerstag (vor Freitag-Ziehung)
if today == 3 and days_since >= 1:
print(" ✅ Donnerstag - generiere für Freitag-Ziehung")
return True
print(" ⏭️ Keine neuen Tipps nötig")
return False
def generate_tips(self, num_tips: int = 10, force: bool = False) -> bool:
"""
Generiert neue Tipps.
Args:
num_tips: Anzahl Tipps
force: Ignoriere needs_new_tips Check
Returns:
True bei Erfolg
"""
print("\n🎯 TIPP-GENERIERUNG")
print("=" * 70)
# Check ob nötig
if not force and not self.needs_new_tips():
print("\n⏭️ Keine Generierung nötig")
return True
print(f"\n🚀 Generiere {num_tips} Ultimate Tipps...")
print("-" * 70)
try:
# Initialisiere Generator
generator = UltimateAIMLEurojackpotGenerator(
self.data_file,
fast_mode=True
)
# Generiere Tipps
tips = generator.generate_ultimate_tips(num_tips=num_tips)
if not tips:
print("\n❌ Keine Tipps generiert")
return False
# Speichere Tipps
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = os.path.join(
self.tips_dir,
f"weekly_tips_{timestamp}.csv"
)
generator.export_tips_to_csv(tips, output_file)
# Update Historie
history = self.load_history()
history["generations"].append({
"timestamp": datetime.now().isoformat(),
"num_tips": len(tips),
"file": os.path.basename(output_file),
"avg_confidence": sum(t['confidence'] for t in tips) / len(tips),
"avg_quality": sum(t['quality'] for t in tips) / len(tips)
})
self.save_history(history)
print("\n" + "=" * 70)
print("✅ TIPPS ERFOLGREICH GENERIERT")
print(f"📁 Datei: {os.path.basename(output_file)}")
print(f"📊 Anzahl: {len(tips)}")
print(f"🎯 Avg Confidence: {history['generations'][-1]['avg_confidence']:.4f}")
print(f"💎 Avg Quality: {history['generations'][-1]['avg_quality']:.4f}")
print("=" * 70)
# Sende Benachrichtigung
try:
# Finde besten Tipp (höchste Confidence)
best_tip = max(tips, key=lambda t: t.get('confidence', 0))
# Formatiere für Notification
best_tip_formatted = {
'main_numbers': best_tip.get('main_numbers', '?'),
'euro_numbers': best_tip.get('euro_numbers', '?'),
'confidence': best_tip.get('confidence', 0),
'strategy': best_tip.get('strategy', 'UNKNOWN')
}
timestamp_formatted = datetime.now().strftime('%Y-%m-%d %H:%M')
self.notifier.send_tips_generated(tips, timestamp_formatted, best_tip_formatted)
except Exception as e:
print(f"⚠️ Benachrichtigung fehlgeschlagen: {e}")
return True
except Exception as e:
print(f"\n❌ Fehler bei Generierung: {e}")
import traceback
traceback.print_exc()
return False
def show_history(self):
"""Zeigt Generierungs-Historie."""
history = self.load_history()
if not history["generations"]:
print("\n ℹ️ Noch keine Generierungen")
return
print("\n📊 GENERIERUNGS-HISTORIE")
print("=" * 70)
print(f"{'Nr':<4} {'Datum':<20} {'Tips':<6} {'Confidence':<12} {'Quality':<12} {'Datei'}")
print("-" * 70)
for i, gen in enumerate(reversed(history["generations"][-10:]), 1):
timestamp = datetime.fromisoformat(gen["timestamp"])
print(f"{i:<4} {timestamp.strftime('%Y-%m-%d %H:%M'):<20} "
f"{gen['num_tips']:<6} {gen['avg_confidence']:<12.4f} "
f"{gen['avg_quality']:<12.4f} {gen['file']}")
print("-" * 70)
print(f"Total: {len(history['generations'])} Generierungen")
def main():
"""Hauptfunktion."""
import argparse
parser = argparse.ArgumentParser(
description="Wöchentlicher Eurojackpot Tipp-Generator"
)
parser.add_argument(
'--force',
action='store_true',
help='Generiere Tipps auch wenn nicht nötig'
)
parser.add_argument(
'--num-tips',
type=int,
default=10,
help='Anzahl Tipps zu generieren (default: 10)'
)
parser.add_argument(
'--history',
action='store_true',
help='Zeige nur Historie'
)
parser.add_argument(
'--data-dir',
type=str,
default="/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data",
help='Daten-Verzeichnis'
)
args = parser.parse_args()
# Initialisiere
generator = WeeklyTipGenerator(args.data_dir)
# Zeige Historie wenn gewünscht
if args.history:
generator.show_history()
return
# Generiere Tipps
success = generator.generate_tips(
num_tips=args.num_tips,
force=args.force
)
# Zeige Historie
generator.show_history()
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()