Initial commit: Lotto number generator project
This project includes multiple AI/ML-based lottery number generators for German Lotto 6aus49, including pattern analysis, weighted predictions, and hybrid approaches. Features automated weekly tip generation, performance tracking, and Telegram bot integration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Lotto 6aus49 Benachrichtigungs-System
|
||||
|
||||
Unterstützt:
|
||||
- Telegram Bot Notifications
|
||||
- Email Notifications (optional)
|
||||
|
||||
Konfiguration über config/notifications.json
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
from typing import List, Dict, Any
|
||||
|
||||
|
||||
class LottoNotifier:
|
||||
"""Benachrichtigungs-System für Lotto 6aus49."""
|
||||
|
||||
def __init__(self, config_path: str = None):
|
||||
"""
|
||||
Initialisiert Notifier.
|
||||
|
||||
Args:
|
||||
config_path: Pfad zur Konfigurationsdatei
|
||||
"""
|
||||
if config_path is None:
|
||||
# Default: config/notifications.json im Projekt-Root
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
project_root = os.path.dirname(os.path.dirname(script_dir))
|
||||
config_path = os.path.join(project_root, 'config', 'notifications.json')
|
||||
|
||||
self.config_path = config_path
|
||||
self.config = self._load_config()
|
||||
|
||||
def _load_config(self) -> dict:
|
||||
"""Lädt Konfiguration."""
|
||||
if not os.path.exists(self.config_path):
|
||||
print(f"⚠️ Konfigurationsdatei nicht gefunden: {self.config_path}")
|
||||
return {
|
||||
"telegram": {"enabled": False},
|
||||
"email": {"enabled": False}
|
||||
}
|
||||
|
||||
try:
|
||||
with open(self.config_path, 'r') as f:
|
||||
config = json.load(f)
|
||||
return config
|
||||
except Exception as e:
|
||||
print(f"⚠️ Fehler beim Laden der Konfiguration: {e}")
|
||||
return {
|
||||
"telegram": {"enabled": False},
|
||||
"email": {"enabled": False}
|
||||
}
|
||||
|
||||
def send_tips_generated(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
||||
"""
|
||||
Sendet Benachrichtigung über generierte Tipps.
|
||||
|
||||
Args:
|
||||
tips: Liste aller generierten Tipps
|
||||
timestamp: Timestamp der Generierung
|
||||
best_tip: Bester Tipp (höchste Confidence)
|
||||
"""
|
||||
if self.config['telegram']['enabled']:
|
||||
self._send_telegram_tips(tips, timestamp, best_tip)
|
||||
|
||||
if self.config['email']['enabled']:
|
||||
self._send_email_tips(tips, timestamp, best_tip)
|
||||
|
||||
def _send_telegram_tips(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
||||
"""Sendet Telegram-Nachricht."""
|
||||
try:
|
||||
bot_token = self.config['telegram']['bot_token']
|
||||
chat_id = self.config['telegram']['chat_id']
|
||||
|
||||
# Formatiere Nachricht
|
||||
message = self._format_telegram_message(tips, timestamp, best_tip)
|
||||
|
||||
# Sende über Telegram Bot API
|
||||
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
||||
data = {
|
||||
"chat_id": chat_id,
|
||||
"text": message,
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
|
||||
response = requests.post(url, data=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Telegram-Benachrichtigung gesendet")
|
||||
else:
|
||||
print(f"⚠️ Telegram-Fehler: {response.status_code}")
|
||||
print(f" Response: {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Telegram-Benachrichtigung fehlgeschlagen: {e}")
|
||||
|
||||
def _format_telegram_message(self, tips: List[Dict], timestamp: str, best_tip: Dict) -> str:
|
||||
"""Formatiert Telegram-Nachricht."""
|
||||
# Header
|
||||
message = "🎲 *LOTTO 6AUS49 - NEUE TIPPS GENERIERT*\n"
|
||||
message += "=" * 40 + "\n\n"
|
||||
|
||||
# Timestamp
|
||||
message += f"📅 *Generiert:* {timestamp}\n"
|
||||
message += f"📊 *Anzahl Tipps:* {len(tips)}\n\n"
|
||||
|
||||
# Bester Tipp
|
||||
message += "⭐ *BESTER TIPP:*\n"
|
||||
numbers_str = ' - '.join([f"{n:02d}" for n in best_tip['numbers']])
|
||||
message += f"🎯 Zahlen: `{numbers_str}`\n"
|
||||
message += f"🌟 Superzahl: `{best_tip['superzahl']}`\n"
|
||||
message += f"📈 Confidence: `{best_tip['confidence']:.4f}`\n"
|
||||
message += f"🎨 Strategie: `{best_tip['strategy']}`\n\n"
|
||||
|
||||
# Statistiken
|
||||
avg_conf = sum(t['confidence'] for t in tips) / len(tips)
|
||||
avg_qual = sum(t['quality'] for t in tips) / len(tips)
|
||||
|
||||
message += "📊 *STATISTIKEN:*\n"
|
||||
message += f"🎯 Ø Confidence: `{avg_conf:.4f}`\n"
|
||||
message += f"💎 Ø Quality: `{avg_qual:.4f}`\n\n"
|
||||
|
||||
# Top 3 Tipps
|
||||
message += "🏆 *TOP 3 TIPPS:*\n"
|
||||
sorted_tips = sorted(tips, key=lambda t: t['confidence'], reverse=True)[:3]
|
||||
|
||||
for i, tip in enumerate(sorted_tips, 1):
|
||||
nums = ' - '.join([f"{n:02d}" for n in tip['numbers']])
|
||||
message += f"{i}. `{nums}` + SZ `{tip['superzahl']}` "
|
||||
message += f"({tip['confidence']:.3f})\n"
|
||||
|
||||
message += "\n🍀 *Viel Glück!*"
|
||||
|
||||
return message
|
||||
|
||||
def _send_email_tips(self, tips: List[Dict], timestamp: str, best_tip: Dict):
|
||||
"""Sendet Email-Benachrichtigung."""
|
||||
# TODO: Email-Versand implementieren wenn gewünscht
|
||||
print("⚠️ Email-Benachrichtigung noch nicht implementiert")
|
||||
|
||||
def send_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
||||
"""
|
||||
Sendet Benachrichtigung über Ziehungs-Ergebnisse und Tipp-Evaluation.
|
||||
|
||||
Args:
|
||||
draw: Dict mit Ziehungsdaten (date, Z1-Z6, SZ)
|
||||
evaluation_summary: Dict mit avg_main, sz_rate
|
||||
best_match: Dict mit main_matches, sz_match
|
||||
"""
|
||||
if self.config['telegram']['enabled']:
|
||||
self._send_telegram_draw_results(draw, evaluation_summary, best_match)
|
||||
|
||||
if self.config['email']['enabled']:
|
||||
self._send_email_draw_results(draw, evaluation_summary, best_match)
|
||||
|
||||
def _send_telegram_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
||||
"""Sendet Telegram-Nachricht mit Ziehungsergebnissen."""
|
||||
try:
|
||||
bot_token = self.config['telegram']['bot_token']
|
||||
chat_id = self.config['telegram']['chat_id']
|
||||
|
||||
# Formatiere Nachricht
|
||||
message = self._format_draw_results_message(draw, evaluation_summary, best_match)
|
||||
|
||||
# Sende über Telegram Bot API
|
||||
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
||||
data = {
|
||||
"chat_id": chat_id,
|
||||
"text": message,
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
|
||||
response = requests.post(url, data=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Telegram-Benachrichtigung gesendet")
|
||||
else:
|
||||
print(f"⚠️ Telegram-Fehler: {response.status_code}")
|
||||
print(f" Response: {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Telegram-Benachrichtigung fehlgeschlagen: {e}")
|
||||
|
||||
def _format_draw_results_message(self, draw: Dict, evaluation_summary: Dict, best_match: Dict) -> str:
|
||||
"""Formatiert Telegram-Nachricht für Ziehungsergebnisse."""
|
||||
# Header
|
||||
message = "🎲 *LOTTO 6AUS49 - ZIEHUNGSERGEBNISSE*\n"
|
||||
message += "=" * 40 + "\n\n"
|
||||
|
||||
# Ziehungsdatum
|
||||
draw_date = draw['date']
|
||||
if hasattr(draw_date, 'strftime'):
|
||||
date_str = draw_date.strftime('%d.%m.%Y')
|
||||
else:
|
||||
date_str = str(draw_date)
|
||||
|
||||
message += f"📅 *Ziehung vom:* {date_str}\n\n"
|
||||
|
||||
# Gezogene Zahlen
|
||||
drawn_numbers = [draw.get(f'Z{i}') for i in range(1, 7)]
|
||||
numbers_str = ' - '.join([f"{n:02d}" for n in drawn_numbers if n is not None])
|
||||
message += f"🎯 *Gewinnzahlen:* `{numbers_str}`\n"
|
||||
|
||||
if draw.get('SZ') is not None:
|
||||
message += f"🌟 *Superzahl:* `{draw['SZ']}`\n\n"
|
||||
else:
|
||||
message += "\n"
|
||||
|
||||
# Evaluation Summary
|
||||
message += "📊 *TIPP-EVALUATION:*\n"
|
||||
if evaluation_summary:
|
||||
avg_main = evaluation_summary.get('avg_main', 0)
|
||||
sz_rate = evaluation_summary.get('sz_rate', 0)
|
||||
message += f"🎯 Ø Treffer Hauptzahlen: `{avg_main:.2f}`\n"
|
||||
message += f"🌟 Superzahl-Rate: `{sz_rate*100:.1f}%`\n\n"
|
||||
|
||||
# Bester Tipp
|
||||
message += "🏆 *BESTER TIPP:*\n"
|
||||
if best_match:
|
||||
main_matches = best_match.get('main_matches', 0)
|
||||
sz_match = best_match.get('sz_match', False)
|
||||
|
||||
# Rating emoji
|
||||
if main_matches == 6 and sz_match:
|
||||
rating = "🏆 JACKPOT!"
|
||||
elif main_matches == 6:
|
||||
rating = "💰 Klasse 2"
|
||||
elif main_matches == 5 and sz_match:
|
||||
rating = "💰 Klasse 3"
|
||||
elif main_matches == 5:
|
||||
rating = "💰 Klasse 4"
|
||||
elif main_matches == 4:
|
||||
rating = "💵 Klasse 6"
|
||||
elif main_matches == 3:
|
||||
rating = "✅ Klasse 8"
|
||||
elif main_matches >= 2:
|
||||
rating = "👍 OK"
|
||||
else:
|
||||
rating = "⚪ Niedrig"
|
||||
|
||||
sz_indicator = "✅" if sz_match else "⚪"
|
||||
message += f"🎯 Treffer Hauptzahlen: `{main_matches}/6`\n"
|
||||
message += f"🌟 Superzahl: {sz_indicator}\n"
|
||||
message += f"📈 Bewertung: {rating}\n"
|
||||
|
||||
message += "\n🔄 *System wurde aktualisiert und trainiert!*"
|
||||
|
||||
return message
|
||||
|
||||
def _send_email_draw_results(self, draw: Dict, evaluation_summary: Dict, best_match: Dict):
|
||||
"""Sendet Email-Benachrichtigung."""
|
||||
# TODO: Email-Versand implementieren wenn gewünscht
|
||||
print("⚠️ Email-Benachrichtigung noch nicht implementiert")
|
||||
|
||||
def send_test_notification(self):
|
||||
"""Sendet Test-Benachrichtigung."""
|
||||
if self.config['telegram']['enabled']:
|
||||
try:
|
||||
bot_token = self.config['telegram']['bot_token']
|
||||
chat_id = self.config['telegram']['chat_id']
|
||||
|
||||
message = "🧪 *LOTTO 6AUS49 TEST*\n\n"
|
||||
message += "✅ Benachrichtigungs-System funktioniert!\n"
|
||||
message += f"📅 {os.popen('date').read().strip()}"
|
||||
|
||||
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
||||
data = {
|
||||
"chat_id": chat_id,
|
||||
"text": message,
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
|
||||
response = requests.post(url, data=data, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Test-Benachrichtigung erfolgreich gesendet")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Fehler: {response.status_code}")
|
||||
print(f" Response: {response.text}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Test fehlgeschlagen: {e}")
|
||||
return False
|
||||
else:
|
||||
print("⚠️ Telegram nicht aktiviert in config/notifications.json")
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
"""Test-Funktion."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Lotto 6aus49 Notifier Test")
|
||||
parser.add_argument(
|
||||
'--test',
|
||||
action='store_true',
|
||||
help='Sende Test-Benachrichtigung'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--config',
|
||||
type=str,
|
||||
help='Pfad zur Config-Datei'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
notifier = LottoNotifier(config_path=args.config)
|
||||
|
||||
if args.test:
|
||||
notifier.send_test_notification()
|
||||
else:
|
||||
# Beispiel-Tipps
|
||||
example_tips = [
|
||||
{
|
||||
'numbers': [7, 14, 21, 28, 35, 42],
|
||||
'superzahl': 3,
|
||||
'confidence': 0.7234,
|
||||
'quality': 0.6891,
|
||||
'strategy': 'PURE-AI'
|
||||
},
|
||||
{
|
||||
'numbers': [2, 11, 19, 27, 36, 45],
|
||||
'superzahl': 7,
|
||||
'confidence': 0.6978,
|
||||
'quality': 0.6543,
|
||||
'strategy': 'HYBRID-OPT'
|
||||
}
|
||||
]
|
||||
|
||||
best = example_tips[0]
|
||||
notifier.send_tips_generated(example_tips, "2024-11-27 16:00", best)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user