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>
241 lines
7.0 KiB
Python
241 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Einfacher Lotto 6aus49 Data Updater
|
|
|
|
Manuelle Eingabe oder CSV-Import von neuen Ziehungen.
|
|
Perfekt als Fallback wenn Web-Scraping oder APIs nicht funktionieren.
|
|
"""
|
|
|
|
import pandas as pd
|
|
from datetime import datetime
|
|
import shutil
|
|
import os
|
|
|
|
|
|
def load_existing_data(data_file):
|
|
"""Lädt existierende Daten."""
|
|
print("📂 Lade existierende Daten...")
|
|
|
|
if not os.path.exists(data_file):
|
|
print(" ⚠️ Datei existiert nicht - erstelle neue")
|
|
return pd.DataFrame(columns=['datum', 'Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'Z6', 'SZ'])
|
|
|
|
df = pd.read_csv(data_file, sep=';')
|
|
df['datum'] = pd.to_datetime(df['datum'], format='%Y-%m-%d', errors='coerce')
|
|
|
|
print(f" ✅ {len(df)} Ziehungen geladen")
|
|
if len(df) > 0:
|
|
print(f" 📅 Neueste: {df['datum'].max().strftime('%Y-%m-%d')}")
|
|
|
|
return df
|
|
|
|
|
|
def create_backup(data_file):
|
|
"""Erstellt Backup."""
|
|
if not os.path.exists(data_file):
|
|
return
|
|
|
|
print("\n💾 Erstelle Backup...")
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
# Backup im Lotto/data/backups Verzeichnis
|
|
parent_dir = os.path.dirname(data_file)
|
|
lotto_dir = os.path.join(parent_dir, "Lotto")
|
|
backup_dir = os.path.join(lotto_dir, "data", "backups")
|
|
os.makedirs(backup_dir, exist_ok=True)
|
|
|
|
backup_file = os.path.join(backup_dir, f"{os.path.basename(data_file)}.backup_{timestamp}")
|
|
shutil.copy2(data_file, backup_file)
|
|
print(f" ✅ Backup: {os.path.basename(backup_file)}")
|
|
|
|
|
|
def manual_input_mode():
|
|
"""Manuelle Eingabe von Ziehungen."""
|
|
print("\n⌨️ MANUELLE EINGABE")
|
|
print("=" * 70)
|
|
print("Format: YYYY-MM-DD Z1 Z2 Z3 Z4 Z5 Z6 SZ")
|
|
print("Beispiel: 2025-01-22 7 14 21 28 35 42 3")
|
|
print("Leer lassen zum Beenden.\n")
|
|
|
|
draws = []
|
|
while True:
|
|
user_input = input(f"Ziehung {len(draws) + 1}: ").strip()
|
|
|
|
if not user_input:
|
|
break
|
|
|
|
try:
|
|
parts = user_input.split()
|
|
if len(parts) != 8:
|
|
print(" ❌ Ungültiges Format. Bitte 8 Werte eingeben.")
|
|
continue
|
|
|
|
date_obj = datetime.strptime(parts[0], '%Y-%m-%d')
|
|
numbers = [int(parts[i]) for i in range(1, 7)]
|
|
superzahl = int(parts[7])
|
|
|
|
# Validierung
|
|
if not all(1 <= n <= 49 for n in numbers):
|
|
print(" ❌ Hauptzahlen müssen zwischen 1 und 49 liegen.")
|
|
continue
|
|
|
|
if not 0 <= superzahl <= 9:
|
|
print(" ❌ Superzahl muss zwischen 0 und 9 liegen.")
|
|
continue
|
|
|
|
if len(set(numbers)) != 6:
|
|
print(" ❌ Hauptzahlen müssen eindeutig sein.")
|
|
continue
|
|
|
|
# Sortiere Zahlen
|
|
numbers_sorted = sorted(numbers)
|
|
|
|
draws.append({
|
|
'datum': date_obj,
|
|
'Z1': numbers_sorted[0],
|
|
'Z2': numbers_sorted[1],
|
|
'Z3': numbers_sorted[2],
|
|
'Z4': numbers_sorted[3],
|
|
'Z5': numbers_sorted[4],
|
|
'Z6': numbers_sorted[5],
|
|
'SZ': superzahl
|
|
})
|
|
|
|
print(f" ✅ Hinzugefügt: {date_obj.strftime('%Y-%m-%d')} | "
|
|
f"{'-'.join(map(str, numbers_sorted))} | SZ: {superzahl}")
|
|
|
|
except ValueError as e:
|
|
print(f" ❌ Fehler: {e}")
|
|
continue
|
|
|
|
return draws
|
|
|
|
|
|
def csv_import_mode():
|
|
"""CSV-Import von Ziehungen."""
|
|
print("\n📁 CSV-IMPORT")
|
|
print("=" * 70)
|
|
print("CSV-Format: datum;Z1;Z2;Z3;Z4;Z5;Z6;SZ")
|
|
print("Beispiel: 2025-01-22;7;14;21;28;35;42;3\n")
|
|
|
|
csv_file = input("Pfad zur CSV-Datei: ").strip()
|
|
|
|
if not os.path.exists(csv_file):
|
|
print(f" ❌ Datei nicht gefunden: {csv_file}")
|
|
return []
|
|
|
|
try:
|
|
df_import = pd.read_csv(csv_file, sep=';')
|
|
df_import['datum'] = pd.to_datetime(df_import['datum'], format='%Y-%m-%d', errors='coerce')
|
|
|
|
draws = df_import.to_dict('records')
|
|
print(f" ✅ {len(draws)} Ziehungen aus CSV geladen")
|
|
|
|
# Zeige erste 3
|
|
for i, draw in enumerate(draws[:3]):
|
|
nums = f"{draw['Z1']}-{draw['Z2']}-{draw['Z3']}-{draw['Z4']}-{draw['Z5']}-{draw['Z6']}"
|
|
print(f" {i+1}. {draw['datum'].strftime('%Y-%m-%d')} | {nums} | SZ: {draw['SZ']}")
|
|
|
|
if len(draws) > 3:
|
|
print(f" ... und {len(draws) - 3} weitere")
|
|
|
|
return draws
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Fehler beim Laden: {e}")
|
|
return []
|
|
|
|
|
|
def merge_and_save(df_existing, new_draws, data_file):
|
|
"""Merged und speichert Daten."""
|
|
if not new_draws:
|
|
print("\n⚠️ Keine neuen Ziehungen zum Hinzufügen")
|
|
return False
|
|
|
|
print(f"\n🔀 Merge {len(new_draws)} neue Ziehung(en)...")
|
|
|
|
df_new = pd.DataFrame(new_draws)
|
|
df_combined = pd.concat([df_existing, df_new], ignore_index=True)
|
|
|
|
# Duplikate entfernen
|
|
before = len(df_combined)
|
|
df_combined = df_combined.drop_duplicates(subset=['datum'], keep='first')
|
|
after = len(df_combined)
|
|
|
|
if before - after > 0:
|
|
print(f" 🗑️ {before - after} Duplikat(e) entfernt")
|
|
|
|
# Sortieren
|
|
df_combined = df_combined.sort_values('datum', ascending=True).reset_index(drop=True)
|
|
|
|
# Speichern
|
|
print(f"\n💾 Speichere {len(df_combined)} Ziehungen...")
|
|
|
|
df_export = df_combined.copy()
|
|
df_export['datum'] = df_export['datum'].dt.strftime('%Y-%m-%d')
|
|
|
|
df_export.to_csv(data_file, sep=';', index=False)
|
|
|
|
print(f" ✅ Gespeichert: {data_file}")
|
|
print(f" 📊 Vorher: {len(df_existing)} | Neu: {len(df_combined) - len(df_existing)} | Gesamt: {len(df_combined)}")
|
|
|
|
return True
|
|
|
|
|
|
def main():
|
|
"""Hauptfunktion."""
|
|
print()
|
|
print("=" * 70)
|
|
print(" LOTTO 6AUS49 SIMPLE UPDATER")
|
|
print(" Manuelle Eingabe oder CSV-Import")
|
|
print("=" * 70)
|
|
print()
|
|
|
|
# Datei-Pfad
|
|
default_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Lotto/data/AlleLottozahlen.csv"
|
|
|
|
print(f"Standard-Datei: {default_file}")
|
|
use_default = input("\nStandard verwenden? (j/n): ").strip().lower()
|
|
|
|
if use_default in ['j', 'ja', 'y', 'yes', '']:
|
|
data_file = default_file
|
|
else:
|
|
data_file = input("Pfad zur Datei: ").strip()
|
|
|
|
print()
|
|
|
|
# Lade existierende Daten
|
|
df_existing = load_existing_data(data_file)
|
|
|
|
# Backup
|
|
create_backup(data_file)
|
|
|
|
# Eingabe-Modus wählen
|
|
print("\n📝 EINGABE-MODUS")
|
|
print("=" * 70)
|
|
print("1. Manuelle Eingabe (einzelne Ziehungen)")
|
|
print("2. CSV-Import (mehrere Ziehungen)")
|
|
print()
|
|
|
|
mode = input("Wahl (1/2): ").strip()
|
|
|
|
if mode == '2':
|
|
new_draws = csv_import_mode()
|
|
else:
|
|
new_draws = manual_input_mode()
|
|
|
|
# Merge und speichern
|
|
success = merge_and_save(df_existing, new_draws, data_file)
|
|
|
|
print()
|
|
print("=" * 70)
|
|
if success:
|
|
print("✅ UPDATE ERFOLGREICH")
|
|
else:
|
|
print("⚠️ KEINE ÄNDERUNGEN")
|
|
print("=" * 70)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|