Remove unreferenced legacy generators, updater, and analysis scripts

The graphify code-graph pass confirmed nothing in the active pipeline
(scripts/automation/, shell entrypoints) imports or calls any of
these - only scripts/generators/ultimate_ai_ml_eurojackpot_generator.py
is wired into automation. Removes:

- ultimate_ai_ml_eurojackpot_generator_v2.1_backup.py, a verbatim
  duplicate of the active generator's classes (UltimateAIMLEurojackpot-
  Generator, EurojackpotAIMLEngine, PatternEngine, HybridOptimizer)
- optimized_eurojackpot_generator.py, a third standalone generator
  documented in README but never imported
- update_historical_data.py, a second data updater never imported
- 12 standalone analysis/utility scripts (bereichsanalyse, positions-
  analyse, NMMHH generators, processors, etc.) with no automation ties

History is preserved in git if anything here turns out to still be
wanted. README still documents most of these - follow-up needed there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 18:53:39 +02:00
co-authored by Claude Sonnet 5
parent 5703e6a12c
commit f23922e05e
16 changed files with 0 additions and 5105 deletions
@@ -1,188 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Bereichskombinationen-Analyse
Analysiert die Kombinationen von Zahlenbereichen in den gezogenen 5er-Kombinationen.
Focus auf Z1-Z4 wie gewünscht.
"""
import pandas as pd
from collections import Counter, defaultdict
def get_range_for_number(number):
"""Bestimmt den Bereich für eine gegebene Zahl."""
if 1 <= number <= 10:
return 'A(1-10)'
elif 11 <= number <= 20:
return 'B(11-20)'
elif 21 <= number <= 30:
return 'C(21-30)'
elif 31 <= number <= 40:
return 'D(31-40)'
elif 41 <= number <= 50:
return 'E(41-50)'
else:
return 'Unknown'
def analyze_range_combinations():
"""Analysiert Bereichskombinationen in Eurojackpot-Ziehungen."""
# Daten laden
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
print(f"🎲 EUROJACKPOT BEREICHSKOMBINATIONEN-ANALYSE")
print(f"Anzahl analysierte Ziehungen: {len(df)}")
print("="*60)
# Analyse für Z1-Z4 (wie gewünscht)
z_columns_z1_z4 = ['Z1', 'Z2', 'Z3', 'Z4']
# Alle Kombinationen sammeln
combinations_z1_z4 = []
range_patterns_z1_z4 = []
for _, row in df.iterrows():
# Bereiche für Z1-Z4 bestimmen
ranges = [get_range_for_number(row[col]) for col in z_columns_z1_z4]
range_pattern = '|'.join(sorted(ranges)) # Sortiert für einheitliche Muster
combinations_z1_z4.append(tuple(ranges))
range_patterns_z1_z4.append(range_pattern)
# Auch vollständige Z1-Z5 Analyse
z_columns_all = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']
combinations_all = []
range_patterns_all = []
for _, row in df.iterrows():
ranges = [get_range_for_number(row[col]) for col in z_columns_all]
range_pattern = '|'.join(sorted(ranges))
combinations_all.append(tuple(ranges))
range_patterns_all.append(range_pattern)
# Häufigkeitsanalyse
print("\n📊 ANALYSE Z1-Z4 (4 Zahlen):")
print("="*40)
pattern_counts_z1_z4 = Counter(range_patterns_z1_z4)
print(f"Häufigste Bereichskombinationen (Z1-Z4):")
for i, (pattern, count) in enumerate(pattern_counts_z1_z4.most_common(15), 1):
percentage = (count / len(df)) * 100
print(f"{i:2}. {pattern:30} {count:3}x ({percentage:4.1f}%)")
print(f"\n📊 VERGLEICH: ANALYSE Z1-Z5 (alle 5 Zahlen):")
print("="*40)
pattern_counts_all = Counter(range_patterns_all)
print(f"Häufigste Bereichskombinationen (Z1-Z5):")
for i, (pattern, count) in enumerate(pattern_counts_all.most_common(15), 1):
percentage = (count / len(df)) * 100
print(f"{i:2}. {pattern:35} {count:3}x ({percentage:4.1f}%)")
# Analyse der Bereichsverteilung in Kombinationen
print(f"\n🎯 BEREICHSVERTEILUNG IN KOMBINATIONEN:")
print("="*50)
# Wie oft kommt jeder Bereich in Z1-Z4 vor?
range_in_combination_counts = defaultdict(int)
for combination in combinations_z1_z4:
for range_name in set(combination): # set() um Duplikate zu vermeiden
range_in_combination_counts[range_name] += 1
print("Häufigkeit der Bereiche in Z1-Z4 Kombinationen:")
for range_name in ['A(1-10)', 'B(11-20)', 'C(21-30)', 'D(31-40)', 'E(41-50)']:
count = range_in_combination_counts[range_name]
percentage = (count / len(df)) * 100
print(f"{range_name}: {count:3} Kombinationen ({percentage:4.1f}%)")
# Analyse: Wie viele verschiedene Bereiche pro Kombination?
print(f"\n📈 BEREICHSVIELFALT PRO KOMBINATION (Z1-Z4):")
print("="*45)
diversity_counts = defaultdict(int)
for combination in combinations_z1_z4:
unique_ranges = len(set(combination))
diversity_counts[unique_ranges] += 1
for num_ranges in sorted(diversity_counts.keys()):
count = diversity_counts[num_ranges]
percentage = (count / len(df)) * 100
print(f"{num_ranges} verschiedene Bereiche: {count:3} Kombinationen ({percentage:4.1f}%)")
# Spezielle Muster
print(f"\n🔍 SPEZIELLE MUSTER (Z1-Z4):")
print("="*35)
# Alle aus dem gleichen Bereich
same_range_count = sum(1 for combo in combinations_z1_z4 if len(set(combo)) == 1)
print(f"Alle 4 Zahlen aus gleichem Bereich: {same_range_count} ({(same_range_count/len(df)*100):.1f}%)")
# Alle aus verschiedenen Bereichen (4 verschiedene)
all_different_count = sum(1 for combo in combinations_z1_z4 if len(set(combo)) == 4)
print(f"Alle 4 Zahlen aus verschiedenen Bereichen: {all_different_count} ({(all_different_count/len(df)*100):.1f}%)")
# Benachbarte Bereiche-Analyse
print(f"\n🏠 BENACHBARTE BEREICHE-ANALYSE (Z1-Z4):")
print("="*40)
adjacent_patterns = {
'A+B': 0, # 1-10 + 11-20
'B+C': 0, # 11-20 + 21-30
'C+D': 0, # 21-30 + 31-40
'D+E': 0, # 31-40 + 41-50
}
for combination in combinations_z1_z4:
ranges_set = set(combination)
if 'A(1-10)' in ranges_set and 'B(11-20)' in ranges_set:
adjacent_patterns['A+B'] += 1
if 'B(11-20)' in ranges_set and 'C(21-30)' in ranges_set:
adjacent_patterns['B+C'] += 1
if 'C(21-30)' in ranges_set and 'D(31-40)' in ranges_set:
adjacent_patterns['C+D'] += 1
if 'D(31-40)' in ranges_set and 'E(41-50)' in ranges_set:
adjacent_patterns['D+E'] += 1
for pattern, count in adjacent_patterns.items():
percentage = (count / len(df)) * 100
print(f"Benachbarte Bereiche {pattern}: {count:3} Kombinationen ({percentage:4.1f}%)")
# Export der Ergebnisse
print(f"\n💾 EXPORT DER ERGEBNISSE:")
print("="*30)
# DataFrame für Z1-Z4 Kombinationen erstellen
results_data = []
for i, row in df.iterrows():
ranges_z1_z4 = [get_range_for_number(row[col]) for col in z_columns_z1_z4]
pattern = '|'.join(sorted(ranges_z1_z4))
diversity = len(set(ranges_z1_z4))
results_data.append({
'datum': row['datum'],
'Z1': row['Z1'],
'Z2': row['Z2'],
'Z3': row['Z3'],
'Z4': row['Z4'],
'Z1_bereich': ranges_z1_z4[0],
'Z2_bereich': ranges_z1_z4[1],
'Z3_bereich': ranges_z1_z4[2],
'Z4_bereich': ranges_z1_z4[3],
'bereichsmuster': pattern,
'anzahl_bereiche': diversity
})
results_df = pd.DataFrame(results_data)
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/bereichskombinationen_z1_z4.csv"
results_df.to_csv(output_file, sep=';', index=False)
print(f"✅ Detailergebnisse gespeichert: bereichskombinationen_z1_z4.csv")
return pattern_counts_z1_z4, pattern_counts_all
if __name__ == "__main__":
analyze_range_combinations()
@@ -1,217 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Bereichsanalyse
Analysiert, in welchen Zahlenbereichen am häufigsten Zahlen gezogen wurden.
"""
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from collections import Counter
def load_drawn_numbers(filepath):
"""Lädt die gezogenen Eurojackpot-Zahlen."""
try:
df = pd.read_csv(filepath, sep=';')
print(f"Gezogene Zahlen geladen: {len(df)} Ziehungen")
print(f"Spalten: {list(df.columns)}")
return df
except Exception as e:
print(f"Fehler beim Laden: {e}")
return None
def analyze_number_ranges(df):
"""Analysiert die Häufigkeit von Zahlen in verschiedenen Bereichen."""
# Alle gezogenen Zahlen sammeln (Z1-Z5)
all_numbers = []
for col in ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']:
all_numbers.extend(df[col].tolist())
print(f"Gesamtanzahl gezogene Zahlen: {len(all_numbers)}")
# Häufigkeit jeder Zahl
number_counts = Counter(all_numbers)
# Bereiche definieren
ranges = {
'1-10': (1, 10),
'11-20': (11, 20),
'21-30': (21, 30),
'31-40': (31, 40),
'41-50': (41, 50)
}
# Analyse pro Bereich
range_analysis = {}
for range_name, (start, end) in ranges.items():
numbers_in_range = [num for num in all_numbers if start <= num <= end]
range_analysis[range_name] = {
'anzahl_ziehungen': len(numbers_in_range),
'prozent': (len(numbers_in_range) / len(all_numbers)) * 100,
'haeufigste_zahl': max(number_counts.items(),
key=lambda x: x[1] if start <= x[0] <= end else 0),
'durchschnitt': np.mean(numbers_in_range) if numbers_in_range else 0,
'zahlen_im_bereich': sorted(set(numbers_in_range))
}
return range_analysis, number_counts
def create_visualizations(range_analysis, number_counts, output_dir):
"""Erstellt Visualisierungen der Analyse."""
# 1. Balkendiagramm: Häufigkeit pro Bereich
plt.figure(figsize=(12, 8))
ranges = list(range_analysis.keys())
counts = [range_analysis[r]['anzahl_ziehungen'] for r in ranges]
percentages = [range_analysis[r]['prozent'] for r in ranges]
plt.subplot(2, 2, 1)
bars = plt.bar(ranges, counts, color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'])
plt.title('Anzahl gezogener Zahlen pro Bereich', fontsize=14, fontweight='bold')
plt.ylabel('Anzahl Ziehungen')
plt.xticks(rotation=45)
# Prozente auf Balken anzeigen
for bar, pct in zip(bars, percentages):
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 5,
f'{pct:.1f}%', ha='center', va='bottom', fontweight='bold')
# 2. Heatmap: Häufigkeit einzelner Zahlen
plt.subplot(2, 2, 2)
numbers = list(range(1, 51))
frequencies = [number_counts.get(num, 0) for num in numbers]
# Als 5x10 Matrix darstellen
freq_matrix = np.array(frequencies).reshape(5, 10)
sns.heatmap(freq_matrix, annot=True, fmt='d', cmap='YlOrRd',
xticklabels=list(range(1, 11)),
yticklabels=[f'{i*10+1}-{(i+1)*10}' for i in range(5)])
plt.title('Häufigkeit einzelner Zahlen', fontsize=14, fontweight='bold')
# 3. Liniendiagramm: Häufigkeit aller Zahlen
plt.subplot(2, 2, 3)
plt.plot(numbers, frequencies, marker='o', linewidth=2, markersize=4)
plt.title('Häufigkeitsverteilung aller Zahlen (1-50)', fontsize=14, fontweight='bold')
plt.xlabel('Zahl')
plt.ylabel('Häufigkeit')
plt.grid(True, alpha=0.3)
# Bereiche farblich markieren
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57']
for i, (range_name, color) in enumerate(zip(range_analysis.keys(), colors)):
start = i * 10 + 1
end = (i + 1) * 10
plt.axvspan(start, end, alpha=0.2, color=color, label=range_name)
plt.legend()
# 4. Pie Chart: Prozentuale Verteilung
plt.subplot(2, 2, 4)
plt.pie(percentages, labels=ranges, autopct='%1.1f%%',
colors=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'],
startangle=90)
plt.title('Prozentuale Verteilung nach Bereichen', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig(f'{output_dir}/eurojackpot_bereichsanalyse.png', dpi=300, bbox_inches='tight')
plt.show()
def print_detailed_analysis(range_analysis, number_counts):
"""Gibt detaillierte Analyseergebnisse aus."""
print("\n" + "="*60)
print("🎯 EUROJACKPOT BEREICHSANALYSE")
print("="*60)
total_numbers = sum(analysis['anzahl_ziehungen'] for analysis in range_analysis.values())
for range_name, analysis in range_analysis.items():
print(f"\n📊 BEREICH {range_name}:")
print(f" Anzahl Ziehungen: {analysis['anzahl_ziehungen']:,}")
print(f" Prozentanteil: {analysis['prozent']:.2f}%")
print(f" Durchschnittswert: {analysis['durchschnitt']:.1f}")
# Top 3 Zahlen in diesem Bereich
start, end = map(int, range_name.split('-'))
range_numbers = [(num, count) for num, count in number_counts.items()
if start <= num <= end]
range_numbers.sort(key=lambda x: x[1], reverse=True)
print(f" Top 3 Zahlen: ", end="")
for i, (num, count) in enumerate(range_numbers[:3]):
print(f"{num} ({count}x)", end="")
if i < 2 and i < len(range_numbers) - 1:
print(", ", end="")
print()
# Allgemeine Statistiken
print(f"\n📈 ALLGEMEINE STATISTIKEN:")
print(f" Gesamte gezogene Zahlen: {total_numbers:,}")
print(f" Durchschnitt pro Bereich: {total_numbers/5:.1f}")
# Häufigste und seltenste Zahlen insgesamt
most_common = number_counts.most_common(5)
least_common = number_counts.most_common()[-5:]
print(f"\n🔥 HÄUFIGSTE ZAHLEN GESAMT:")
for i, (num, count) in enumerate(most_common, 1):
print(f" {i}. Zahl {num}: {count} mal gezogen")
print(f"\n❄️ SELTENSTE ZAHLEN GESAMT:")
for i, (num, count) in enumerate(reversed(least_common), 1):
print(f" {i}. Zahl {num}: {count} mal gezogen")
# Empfehlungen
print(f"\n💡 ERKENNTNISSE:")
best_range = max(range_analysis.keys(), key=lambda x: range_analysis[x]['prozent'])
worst_range = min(range_analysis.keys(), key=lambda x: range_analysis[x]['prozent'])
print(f" • Bester Bereich: {best_range} ({range_analysis[best_range]['prozent']:.1f}%)")
print(f" • Schwächster Bereich: {worst_range} ({range_analysis[worst_range]['prozent']:.1f}%)")
print(f" • Unterschied: {range_analysis[best_range]['prozent'] - range_analysis[worst_range]['prozent']:.1f} Prozentpunkte")
def main():
"""Hauptfunktion."""
# Pfade
input_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv"
output_dir = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot"
# Daten laden
print("🔄 Lade Eurojackpot-Daten...")
df = load_drawn_numbers(input_file)
if df is None:
print("❌ Fehler beim Laden der Daten!")
return
# Analyse durchführen
print("\n🔍 Führe Bereichsanalyse durch...")
range_analysis, number_counts = analyze_number_ranges(df)
# Ergebnisse ausgeben
print_detailed_analysis(range_analysis, number_counts)
# Visualisierungen erstellen
print(f"\n📊 Erstelle Visualisierungen...")
try:
create_visualizations(range_analysis, number_counts, output_dir)
print(f"✅ Diagramm gespeichert: {output_dir}/eurojackpot_bereichsanalyse.png")
except Exception as e:
print(f"⚠️ Visualisierung konnte nicht erstellt werden: {e}")
print("💡 Installieren Sie matplotlib und seaborn: pip install matplotlib seaborn")
# CSV-Export der Analyse
results_df = pd.DataFrame.from_dict(range_analysis, orient='index')
results_df.to_csv(f'{output_dir}/bereichsanalyse_ergebnisse.csv', sep=';')
print(f"✅ Ergebnisse gespeichert: {output_dir}/bereichsanalyse_ergebnisse.csv")
if __name__ == "__main__":
main()
-208
View File
@@ -1,208 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Positionsanalyse
Analysiert, welche Bereiche an welchen Positionen (Z1, Z2, Z3, Z4, Z5) am häufigsten stehen.
"""
import pandas as pd
from collections import defaultdict
import numpy as np
def get_range_for_number(number):
"""Bestimmt den Bereich für eine gegebene Zahl."""
if 1 <= number <= 10:
return 'A(1-10)'
elif 11 <= number <= 20:
return 'B(11-20)'
elif 21 <= number <= 30:
return 'C(21-30)'
elif 31 <= number <= 40:
return 'D(31-40)'
elif 41 <= number <= 50:
return 'E(41-50)'
else:
return 'Unknown'
def analyze_positions():
"""Führt eine detaillierte Positionsanalyse durch."""
# Daten laden
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
print(f"🎯 EUROJACKPOT POSITIONSANALYSE")
print(f"Anzahl analysierte Ziehungen: {len(df)}")
print("="*60)
# Positionen definieren
positions = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']
ranges = ['A(1-10)', 'B(11-20)', 'C(21-30)', 'D(31-40)', 'E(41-50)']
# Matrix für Positions-Bereich-Kombinationen
position_range_matrix = defaultdict(lambda: defaultdict(int))
# Daten sammeln
for _, row in df.iterrows():
for pos in positions:
range_name = get_range_for_number(row[pos])
position_range_matrix[pos][range_name] += 1
# 1. Übersichtstabelle erstellen
print(f"\n📊 POSITIONS-BEREICH-MATRIX:")
print("="*60)
print(f"{'Position':<8} {'A(1-10)':<12} {'B(11-20)':<12} {'C(21-30)':<12} {'D(31-40)':<12} {'E(41-50)':<12}")
print("-" * 60)
for pos in positions:
line = f"{pos:<8} "
for range_name in ranges:
count = position_range_matrix[pos][range_name]
percentage = (count / len(df)) * 100
line += f"{count:3}({percentage:4.1f}%) "
print(line)
# 2. Beste Bereiche pro Position
print(f"\n🏆 BESTE BEREICHE PRO POSITION:")
print("="*40)
for pos in positions:
best_range = max(ranges, key=lambda r: position_range_matrix[pos][r])
best_count = position_range_matrix[pos][best_range]
best_percentage = (best_count / len(df)) * 100
# Alle Bereiche für diese Position sortiert
sorted_ranges = sorted(ranges, key=lambda r: position_range_matrix[pos][r], reverse=True)
print(f"\n{pos}: {best_range} führt mit {best_count} ({best_percentage:.1f}%)")
print(f" Ranking: ", end="")
for i, range_name in enumerate(sorted_ranges, 1):
count = position_range_matrix[pos][range_name]
percentage = (count / len(df)) * 100
print(f"{i}.{range_name}({percentage:.1f}%)", end="")
if i < len(sorted_ranges):
print(" > ", end="")
print()
# 3. Beste Positionen pro Bereich
print(f"\n🎯 BESTE POSITIONEN PRO BEREICH:")
print("="*40)
for range_name in ranges:
best_position = max(positions, key=lambda p: position_range_matrix[p][range_name])
best_count = position_range_matrix[best_position][range_name]
best_percentage = (best_count / len(df)) * 100
# Alle Positionen für diesen Bereich sortiert
sorted_positions = sorted(positions, key=lambda p: position_range_matrix[p][range_name], reverse=True)
print(f"\n{range_name}: Position {best_position} führt mit {best_count} ({best_percentage:.1f}%)")
print(f" Ranking: ", end="")
for i, pos in enumerate(sorted_positions, 1):
count = position_range_matrix[pos][range_name]
percentage = (count / len(df)) * 100
print(f"{i}.{pos}({percentage:.1f}%)", end="")
if i < len(sorted_positions):
print(" > ", end="")
print()
# 4. Spezielle Analysen
print(f"\n📈 SPEZIELLE POSITIONSANALYSEN:")
print("="*45)
# Niedrige vs. hohe Bereiche pro Position
for pos in positions:
low_ranges = position_range_matrix[pos]['A(1-10)'] + position_range_matrix[pos]['B(11-20)']
high_ranges = position_range_matrix[pos]['D(31-40)'] + position_range_matrix[pos]['E(41-50)']
middle_range = position_range_matrix[pos]['C(21-30)']
low_pct = (low_ranges / len(df)) * 100
high_pct = (high_ranges / len(df)) * 100
middle_pct = (middle_range / len(df)) * 100
print(f"{pos}: Niedrig(A+B)={low_pct:4.1f}% | Mitte(C)={middle_pct:4.1f}% | Hoch(D+E)={high_pct:4.1f}%")
# 5. Gleichverteilungs-Analyse
print(f"\n⚖️ GLEICHVERTEILUNGS-ANALYSE:")
print("="*35)
expected_per_range = len(df) / 5 # Erwartete Gleichverteilung
print(f"Erwartete Gleichverteilung pro Bereich und Position: {expected_per_range:.1f}")
print(f"\nAbweichungen von der Gleichverteilung:")
for pos in positions:
print(f"\n{pos}:")
for range_name in ranges:
actual = position_range_matrix[pos][range_name]
deviation = actual - expected_per_range
deviation_pct = (deviation / expected_per_range) * 100
symbol = "📈" if deviation > 0 else "📉" if deviation < 0 else "⚖️"
print(f" {range_name}: {actual:3} ({deviation:+4.1f}, {deviation_pct:+5.1f}%) {symbol}")
# 6. Heatmap-Daten für Export
print(f"\n💾 DATENEXPORT:")
print("="*20)
# Erstelle eine Matrix für bessere Visualisierung
matrix_data = []
for pos in positions:
row_data = {'Position': pos}
for range_name in ranges:
count = position_range_matrix[pos][range_name]
percentage = (count / len(df)) * 100
row_data[range_name] = count
row_data[f"{range_name}_Prozent"] = percentage
matrix_data.append(row_data)
matrix_df = pd.DataFrame(matrix_data)
# Zusätzliche Statistiken hinzufügen
stats_data = []
for _, row in df.iterrows():
row_data = {'datum': row['datum']}
for pos in positions:
row_data[f"{pos}_Zahl"] = row[pos]
row_data[f"{pos}_Bereich"] = get_range_for_number(row[pos])
stats_data.append(row_data)
stats_df = pd.DataFrame(stats_data)
# Export
matrix_output = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/positions_matrix.csv"
stats_output = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/positions_details.csv"
matrix_df.to_csv(matrix_output, sep=';', index=False)
stats_df.to_csv(stats_output, sep=';', index=False)
print(f"✅ Positionsmatrix gespeichert: positions_matrix.csv")
print(f"✅ Detaildaten gespeichert: positions_details.csv")
# 7. Strategische Empfehlungen
print(f"\n💡 STRATEGISCHE EMPFEHLUNGEN:")
print("="*35)
# Finde die besten Kombinationen pro Position
recommendations = {}
for pos in positions:
best_range = max(ranges, key=lambda r: position_range_matrix[pos][r])
recommendations[pos] = best_range
print(f"Optimale Bereichsauswahl pro Position:")
for pos, best_range in recommendations.items():
count = position_range_matrix[pos][best_range]
percentage = (count / len(df)) * 100
print(f" {pos}: {best_range} ({percentage:.1f}%)")
# Berechne theoretische Erfolgswahrscheinlichkeit
theoretical_success = 1.0
for pos, best_range in recommendations.items():
prob = position_range_matrix[pos][best_range] / len(df)
theoretical_success *= prob
print(f"\nTheoretische Erfolgswahrscheinlichkeit dieser Kombination: {theoretical_success*100:.4f}%")
return position_range_matrix, matrix_df
if __name__ == "__main__":
analyze_positions()
@@ -1,54 +0,0 @@
#!/usr/bin/env python3
"""
Einfache Eurojackpot Bereichsanalyse
"""
import pandas as pd
from collections import Counter
def analyze_ranges():
"""Analysiert Zahlenbereiche in Eurojackpot-Daten."""
# Daten laden
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv", sep=';')
print(f"Anzahl Ziehungen: {len(df)}")
# Alle Zahlen sammeln
all_numbers = []
for col in ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']:
all_numbers.extend(df[col].tolist())
# Bereiche definieren
ranges = {
'1-10': list(range(1, 11)),
'11-20': list(range(11, 21)),
'21-30': list(range(21, 31)),
'31-40': list(range(31, 41)),
'41-50': list(range(41, 51))
}
print(f"\nGesamt gezogene Zahlen: {len(all_numbers)}")
print("="*50)
# Analyse pro Bereich
for range_name, range_numbers in ranges.items():
count = sum(1 for num in all_numbers if num in range_numbers)
percentage = (count / len(all_numbers)) * 100
print(f"{range_name:6}: {count:4} Zahlen ({percentage:5.1f}%)")
print("="*50)
# Häufigste Zahlen
number_counts = Counter(all_numbers)
print("\nHäufigste 10 Zahlen:")
for num, count in number_counts.most_common(10):
print(f"Zahl {num:2}: {count:3} mal")
print("\nSeltenste 10 Zahlen:")
for num, count in number_counts.most_common()[-10:]:
print(f"Zahl {num:2}: {count:3} mal")
if __name__ == "__main__":
analyze_ranges()
@@ -1,270 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Treffer-Analyse (umschlüsselte Werte)
Analysiert, wo die größten Treffer-Wahrscheinlichkeiten bei den umschlüsselten Werten liegen.
"""
import pandas as pd
from collections import Counter, defaultdict
import numpy as np
def analyze_hit_probabilities():
"""Analysiert die Treffer-Wahrscheinlichkeiten der umschlüsselten Werte."""
# Umschlüsselte Daten laden
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/AlleEurojackpotzahlen_umschluesselt.csv", sep=';')
print("🎯 TREFFER-ANALYSE UMSCHLÜSSELTE WERTE (1-10)")
print("="*60)
print(f"Analysierte Ziehungen: {len(df)}")
# 1. Einzelne Gruppen-Wahrscheinlichkeiten pro Position
print(f"\n🏆 HÖCHSTE TREFFER-WAHRSCHEINLICHKEITEN PRO POSITION:")
print("="*55)
positions = ['z1', 'z2', 'z3', 'z4', 'z5']
position_stats = {}
for pos in positions:
group_counts = Counter(df[pos])
total = len(df)
# Beste Gruppe für diese Position
best_group = max(group_counts, key=group_counts.get)
best_count = group_counts[best_group]
best_probability = (best_count / total) * 100
position_stats[pos] = {
'best_group': best_group,
'probability': best_probability,
'count': best_count,
'all_groups': group_counts
}
print(f"\n{pos.upper()}: Gruppe {best_group} führt mit {best_probability:.1f}% ({best_count}/{total})")
# Top 3 für diese Position
top_3 = group_counts.most_common(3)
print(f" Top 3: ", end="")
for i, (group, count) in enumerate(top_3):
prob = (count / total) * 100
print(f"{i+1}.Gruppe {group}({prob:.1f}%)", end="")
if i < 2:
print(" > ", end="")
print()
# 2. Beste Gesamtkombination
print(f"\n🔥 OPTIMAL-KOMBINATION (höchste Einzelwahrscheinlichkeiten):")
print("="*60)
optimal_combination = []
total_probability = 1.0
for pos in positions:
best_group = position_stats[pos]['best_group']
probability = position_stats[pos]['probability'] / 100
optimal_combination.append(best_group)
total_probability *= probability
print(f"{pos}: Gruppe {best_group} ({position_stats[pos]['probability']:.1f}%)")
optimal_string = '-'.join(map(str, optimal_combination))
print(f"\nOptimal-Kombination: {optimal_string}")
print(f"Theoretische Wahrscheinlichkeit: {total_probability*100:.6f}%")
print(f"Das entspricht etwa 1 in {1/total_probability:,.0f} Ziehungen")
# 3. Tatsächlich aufgetretene häufigste Kombinationen
print(f"\n📊 REAL AUFGETRETENE HÄUFIGSTE KOMBINATIONEN:")
print("="*50)
combination_counts = Counter(df['kombination_umschluesselt'])
print(f"Top 20 real aufgetretene Kombinationen:")
for i, (combination, count) in enumerate(combination_counts.most_common(20), 1):
probability = (count / len(df)) * 100
print(f"{i:2}. {combination:15} {count}x ({probability:.2f}%)")
# 4. Bereichs-Kombinationen mit höchster Wahrscheinlichkeit
print(f"\n🎲 BEREICHS-KOMBINATIONEN MIT HÖCHSTER WAHRSCHEINLICHKEIT:")
print("="*60)
# Niedrig (1-3), Mittel (4-7), Hoch (8-10) Kombinationen
range_combinations = defaultdict(int)
for _, row in df.iterrows():
ranges = []
for pos in positions:
val = row[pos]
if 1 <= val <= 3:
ranges.append('N') # Niedrig
elif 4 <= val <= 7:
ranges.append('M') # Mittel
else:
ranges.append('H') # Hoch
range_pattern = ''.join(ranges)
range_combinations[range_pattern] += 1
print(f"Häufigste Bereichsmuster (N=Niedrig1-3, M=Mittel4-7, H=Hoch8-10):")
sorted_patterns = sorted(range_combinations.items(), key=lambda x: x[1], reverse=True)
for i, (pattern, count) in enumerate(sorted_patterns[:15], 1):
probability = (count / len(df)) * 100
pattern_readable = pattern.replace('N', 'Niedrig').replace('M', 'Mittel').replace('H', 'Hoch')
print(f"{i:2}. {pattern:5} ({pattern_readable:25}) {count:3}x ({probability:5.1f}%)")
# 5. Positions-spezifische Empfehlungen
print(f"\n💡 POSITIONS-SPEZIFISCHE EMPFEHLUNGEN:")
print("="*45)
recommendations = {}
for pos in positions:
group_counts = position_stats[pos]['all_groups']
total = len(df)
# Top 3 Gruppen für maximale Abdeckung
top_groups = [group for group, count in group_counts.most_common(3)]
top_coverage = sum(group_counts[group] for group in top_groups)
coverage_percentage = (top_coverage / total) * 100
recommendations[pos] = {
'top_groups': top_groups,
'coverage': coverage_percentage
}
print(f"\n{pos.upper()}: Empfohlene Gruppen {top_groups}")
print(f" Abdeckung: {coverage_percentage:.1f}% aller Ziehungen")
# Wahrscheinlichkeitsverteilung
print(f" Verteilung: ", end="")
for group in top_groups:
prob = (group_counts[group] / total) * 100
print(f"Gruppe {group}({prob:.1f}%)", end="")
if group != top_groups[-1]:
print(", ", end="")
print()
# 6. Strategische Kombinationen
print(f"\n🎯 STRATEGISCHE KOMBINATIONEN FÜR MAXIMALE TREFFER:")
print("="*55)
# Berechne verschiedene Strategien
strategies = {
'Konservativ': {
'z1': [1, 2], # Top 2 der Position z1
'z2': [3, 4], # Top 2 der Position z2
'z3': [5, 6], # Top 2 der Position z3
'z4': [7, 8], # Top 2 der Position z4
'z5': [9, 10] # Top 2 der Position z5
},
'Ausgewogen': {
'z1': [1, 2, 3], # Top 3 jeder Position
'z2': [3, 4, 5],
'z3': [4, 5, 6, 7],
'z4': [6, 7, 8],
'z5': [8, 9, 10]
},
'Optimal': {} # Wird basierend auf tatsächlichen Daten gefüllt
}
# Optimal-Strategie basierend auf echten Top-3 pro Position
for pos in positions:
top_3_groups = recommendations[pos]['top_groups']
strategies['Optimal'][pos] = top_3_groups
for strategy_name, strategy in strategies.items():
if strategy: # Nur wenn Strategie gefüllt ist
print(f"\n{strategy_name}-Strategie:")
total_combinations = 1
coverage_per_position = []
for pos in positions:
recommended_groups = strategy[pos]
pos_stats = position_stats[pos]['all_groups']
total_pos = len(df)
# Abdeckung dieser Gruppen
coverage = sum(pos_stats.get(group, 0) for group in recommended_groups)
coverage_pct = (coverage / total_pos) * 100
coverage_per_position.append(coverage_pct)
total_combinations *= len(recommended_groups)
print(f" {pos}: Gruppen {recommended_groups} ({coverage_pct:.1f}% Abdeckung)")
avg_coverage = np.mean(coverage_per_position)
print(f" Durchschnittliche Abdeckung: {avg_coverage:.1f}%")
print(f" Mögliche Kombinationen: {total_combinations:,}")
# 7. Heiße und kalte Zahlen
print(f"\n🔥❄️ HEISSE UND KALTE GRUPPEN:")
print("="*35)
# Alle Gruppen über alle Positionen sammeln
all_groups = []
for pos in positions:
all_groups.extend(df[pos].tolist())
group_total_counts = Counter(all_groups)
total_appearances = len(all_groups)
expected_per_group = total_appearances / 10 # 10 Gruppen
print(f"Erwartete Häufigkeit pro Gruppe: {expected_per_group:.1f}")
print(f"\nHeisse Gruppen (über Erwartung):")
hot_groups = []
for group in range(1, 11):
actual = group_total_counts.get(group, 0)
deviation = actual - expected_per_group
if deviation > 0:
hot_groups.append((group, actual, deviation))
hot_groups.sort(key=lambda x: x[2], reverse=True)
for group, count, deviation in hot_groups:
percentage = (count / total_appearances) * 100
print(f" Gruppe {group}: {count} (+{deviation:.1f}, {percentage:.1f}%)")
print(f"\nKalte Gruppen (unter Erwartung):")
cold_groups = []
for group in range(1, 11):
actual = group_total_counts.get(group, 0)
deviation = actual - expected_per_group
if deviation < 0:
cold_groups.append((group, actual, deviation))
cold_groups.sort(key=lambda x: x[2])
for group, count, deviation in cold_groups:
percentage = (count / total_appearances) * 100
print(f" Gruppe {group}: {count} ({deviation:.1f}, {percentage:.1f}%)")
# 8. Export der Empfehlungen
print(f"\n💾 EMPFEHLUNGEN EXPORT:")
print("="*25)
# Erstelle Empfehlungs-DataFrame
recommendation_data = []
# Für jede Position die besten Empfehlungen
for pos in positions:
pos_recommendations = recommendations[pos]
for group in pos_recommendations['top_groups']:
prob = (position_stats[pos]['all_groups'][group] / len(df)) * 100
recommendation_data.append({
'position': pos,
'gruppe': group,
'wahrscheinlichkeit_prozent': prob,
'anzahl_auftreten': position_stats[pos]['all_groups'][group],
'empfehlung_rang': pos_recommendations['top_groups'].index(group) + 1
})
rec_df = pd.DataFrame(recommendation_data)
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/treffer_empfehlungen_umschluesselt.csv"
rec_df.to_csv(output_file, sep=';', index=False)
print(f"✅ Empfehlungen gespeichert: treffer_empfehlungen_umschluesselt.csv")
return position_stats, recommendations
if __name__ == "__main__":
analyze_hit_probabilities()
-141
View File
@@ -1,141 +0,0 @@
import csv
from itertools import combinations
import time
print("=== EUROJACKPOT KOMBINATIONS-GENERATOR ===")
print("Erstellt alle möglichen Kombinationen mit Status (gezogen/nicht gezogen)")
print()
# Pfade
eurojackpot_file = '/Users/sebastianfrohlich/Downloads/EJ_ab_2018.csv'
output_file = '/Users/sebastianfrohlich/Desktop/Alle_Eurojackpot_Kombinationen_mit_Status.csv'
missing_file = '/Users/sebastianfrohlich/Desktop/Fehlende_Eurojackpot_Kombinationen.csv'
# Schritt 1: Einlesen der gezogenen Kombinationen
print("Schritt 1: Lade gezogene Eurojackpot-Kombinationen...")
existing_combinations = set()
try:
with open(eurojackpot_file, 'r', encoding='utf-8') as file:
lines = file.readlines()
for line in lines[1:]: # Header überspringen
parts = line.strip().split(';')
if len(parts) >= 6: # Mindestens Datum + 5 Zahlen
try:
numbers = []
for i in range(1, 6): # Spalten 1-5 (nach Datum)
if i < len(parts) and parts[i].strip().isdigit():
numbers.append(int(parts[i].strip()))
if len(numbers) == 5: # Vollständige Kombination
combo = frozenset(numbers)
existing_combinations.add(combo)
except (ValueError, IndexError):
continue
print(f"{len(existing_combinations)} gezogene Kombinationen geladen")
# Beispiele anzeigen
if existing_combinations:
print(" Beispiele:")
for i, combo in enumerate(list(existing_combinations)[:3]):
sorted_combo = sorted(list(combo))
print(f" {sorted_combo}")
if len(existing_combinations) > 3:
print(f" ... und {len(existing_combinations)-3} weitere")
except FileNotFoundError:
print(f" ⚠️ Datei nicht gefunden: {eurojackpot_file}")
existing_combinations = set()
except Exception as e:
print(f" ⚠️ Fehler beim Lesen: {e}")
existing_combinations = set()
print()
# Schritt 2: Generierung aller möglichen Kombinationen
print("Schritt 2: Generiere alle möglichen Kombinationen (5 aus 50)...")
total_combinations = 2118760 # C(50,5)
print(f" Gesamtanzahl zu verarbeitender Kombinationen: {total_combinations:,}")
all_combinations = []
count = 0
start_time = time.time()
for combo in combinations(range(1, 51), 5):
count += 1
# Fortschritt anzeigen
if count % 100000 == 0:
elapsed = time.time() - start_time
rate = count / elapsed if elapsed > 0 else 0
remaining = (total_combinations - count) / rate if rate > 0 else 0
print(f" Fortschritt: {count:,} / {total_combinations:,} "
f"({count/total_combinations*100:.1f}%) "
f"- {rate:,.0f}/s - noch ~{remaining/60:.1f} min")
# Prüfen ob Kombination bereits gezogen wurde
sorted_combo = sorted(combo)
is_drawn = 1 if frozenset(combo) in existing_combinations else 0
# Zur Liste hinzufügen (Z1, Z2, Z3, Z4, Z5, gezogen)
combination_row = sorted_combo + [is_drawn]
all_combinations.append(combination_row)
print(f" ✓ Alle {len(all_combinations):,} Kombinationen generiert")
print()
# Schritt 3: Statistiken berechnen
print("Schritt 3: Berechne Statistiken...")
drawn_combinations = sum(1 for combo in all_combinations if combo[5] == 1)
undrawn_combinations = len(all_combinations) - drawn_combinations
print(f" Gesamt mögliche Kombinationen: {len(all_combinations):,}")
print(f" Bereits gezogene Kombinationen: {drawn_combinations:,}")
print(f" Noch nicht gezogene Kombinationen: {undrawn_combinations:,}")
if len(all_combinations) > 0:
percentage = drawn_combinations / len(all_combinations) * 100
print(f" Anteil gezogener Kombinationen: {percentage:.6f}%")
print()
# Schritt 4: Hauptdatei speichern
print("Schritt 4: Speichere Hauptdatei...")
try:
with open(output_file, 'w', newline='', encoding='utf-8') as outfile:
writer = csv.writer(outfile, delimiter=';')
writer.writerow(['Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'gezogen']) # Header
for combo in all_combinations:
writer.writerow(combo)
print(f" ✓ Hauptdatei gespeichert: {output_file}")
except Exception as e:
print(f" ⚠️ Fehler beim Speichern der Hauptdatei: {e}")
# Schritt 5: Datei mit fehlenden Kombinationen speichern
print("Schritt 5: Speichere Datei mit fehlenden Kombinationen...")
try:
missing_combinations = [combo[:5] for combo in all_combinations if combo[5] == 0]
with open(missing_file, 'w', newline='', encoding='utf-8') as outfile:
writer = csv.writer(outfile, delimiter=';')
writer.writerow(['Z1', 'Z2', 'Z3', 'Z4', 'Z5']) # Header
for combo in missing_combinations:
writer.writerow(combo)
print(f" ✓ Datei mit fehlenden Kombinationen gespeichert: {missing_file}")
print(f"{len(missing_combinations):,} fehlende Kombinationen")
except Exception as e:
print(f" ⚠️ Fehler beim Speichern der fehlenden Kombinationen: {e}")
print()
print("=== FERTIG ===")
print("Erstellte Dateien:")
print(f"1. {output_file}")
print(f" - Alle {len(all_combinations):,} Kombinationen mit Status")
print(f"2. {missing_file}")
if 'missing_combinations' in locals():
print(f" - {len(missing_combinations):,} noch nicht gezogene Kombinationen")
print()
print("Format der Hauptdatei:")
print("Z1;Z2;Z3;Z4;Z5;gezogen")
print("1;2;3;4;5;0")
print("...")
@@ -1,806 +0,0 @@
#!/usr/bin/env python3
"""
Ultimativer Eurojackpot Tipp-Generator mit Multi-Ziehungs-Trend-Analyse
Kombiniert multiple Optimierungsstrategien:
- Historische Häufigkeitsanalyse
- Positionsbasierte Gewichtung
- Multi-Ziehungs-Trend-Analyse (NEU!)
- Zahlen-Momentum-Tracking
- Sequenzielle Abhängigkeiten
- Zyklische Muster-Erkennung
"""
import pandas as pd
import random
import numpy as np
from itertools import combinations
from collections import Counter, defaultdict, deque
import datetime
class UltimativerEurojackpotGenerator:
def __init__(self, data_path="/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleEurojackpotzahlen.csv"):
self.data_path = data_path
self.df = None
self.drawn_combinations = set()
# Basis-Analyse (Original)
self.number_frequencies = Counter()
self.position_frequencies = defaultdict(Counter)
self.pattern_frequencies = Counter()
self.supernumber_frequencies = {'sz1': Counter(), 'sz2': Counter()}
self.number_distances = []
# Multi-Ziehungs-Trend-Analyse (NEU!)
self.number_sequences = defaultdict(list)
self.momentum_scores = {}
self.trend_predictions = {}
self.sequential_dependencies = defaultdict(lambda: defaultdict(int))
self.cycle_patterns = {}
self.hot_numbers = []
self.warm_numbers = []
self.cold_numbers = []
# Initialisierung
self.load_and_analyze_all_data()
def load_and_analyze_all_data(self):
"""Lädt Daten und führt alle Analysen durch."""
try:
self.df = pd.read_csv(self.data_path, sep=';')
# Chronologische Sortierung für Trend-Analyse
if 'Datum' in self.df.columns:
self.df['Datum'] = pd.to_datetime(self.df['Datum'], format='%d.%m.%Y')
self.df = self.df.sort_values('Datum')
print(f"🚀 ULTIMATIVER EUROJACKPOT GENERATOR")
print("=" * 60)
print(f"📊 Analysiere {len(self.df)} Ziehungen mit Multi-Trend-Analyse...")
# Basis-Analysen durchführen
self._perform_basic_analysis()
# Multi-Ziehungs-Trend-Analysen durchführen (NEU!)
self._perform_momentum_analysis()
self._perform_sequential_analysis()
self._perform_cycle_analysis()
self._generate_trend_predictions()
print(f"✅ Komplette Analyse abgeschlossen!")
self._print_ultimate_analysis_summary()
except Exception as e:
print(f"❌ Fehler beim Laden der Daten: {e}")
return False
return True
def _perform_basic_analysis(self):
"""Führt die ursprünglichen Basis-Analysen durch."""
for _, row in self.df.iterrows():
# Gezogene Kombinationen
combo = tuple(sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']]))
self.drawn_combinations.add(combo)
# Zahlenfrequenzen
numbers = [row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']]
for num in numbers:
self.number_frequencies[num] += 1
# Positionsfrequenzen
sorted_numbers = sorted(numbers)
for i, num in enumerate(sorted_numbers):
self.position_frequencies[f'pos_{i+1}'][num] += 1
# Muster analysieren
pattern = self._get_pattern(sorted_numbers)
self.pattern_frequencies[pattern] += 1
# Superzahlen
self.supernumber_frequencies['sz1'][row['SZ1']] += 1
self.supernumber_frequencies['sz2'][row['SZ2']] += 1
# Zahlenabstände
distances = [sorted_numbers[i+1] - sorted_numbers[i] for i in range(4)]
self.number_distances.extend(distances)
def _perform_momentum_analysis(self, window_size=15):
"""Führt Multi-Ziehungs-Momentum-Analyse durch (NEU!)"""
print(f"\n🔥 MOMENTUM-ANALYSE (Fenster: {window_size})")
# Zahlensequenzen über Zeit aufbauen
for number in range(1, 51):
sequence = []
for _, row in self.df.iterrows():
drawn_numbers = [row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']]
sequence.append(1 if number in drawn_numbers else 0)
self.number_sequences[number] = sequence
# Momentum-Scores berechnen
momentum_results = {}
for number in range(1, 51):
recent_sequence = self.number_sequences[number][-window_size:]
hit_rate = sum(recent_sequence) / len(recent_sequence)
trend_score = self._calculate_trend_score(recent_sequence)
recency_score = self._calculate_recency_score(recent_sequence)
# Kombinierter Momentum-Score mit Gewichtung
momentum_score = (hit_rate * 0.4) + (trend_score * 0.4) + (recency_score * 0.2)
momentum_results[number] = {
'hit_rate': hit_rate,
'trend_score': trend_score,
'recency_score': recency_score,
'momentum_score': momentum_score,
'status': self._get_momentum_status(momentum_score)
}
self.momentum_scores = momentum_results
# Zahlen in Kategorien einteilen
sorted_momentum = sorted(momentum_results.items(),
key=lambda x: x[1]['momentum_score'], reverse=True)
self.hot_numbers = [num for num, data in sorted_momentum[:20]
if data['momentum_score'] > 0.35]
self.warm_numbers = [num for num, data in sorted_momentum[20:35]
if 0.2 <= data['momentum_score'] <= 0.35]
self.cold_numbers = [num for num, data in sorted_momentum[35:]
if data['momentum_score'] < 0.2][:15]
print(f"🔥 {len(self.hot_numbers)} heiße Zahlen identifiziert")
print(f"🌡️ {len(self.warm_numbers)} warme Zahlen identifiziert")
print(f"🧊 {len(self.cold_numbers)} kalte Zahlen identifiziert")
def _perform_sequential_analysis(self, look_back=3):
"""Analysiert sequenzielle Abhängigkeiten zwischen Ziehungen (NEU!)"""
print(f"\n🔗 SEQUENZIELLE ABHÄNGIGKEITEN (Look-back: {look_back})")
for i in range(look_back, len(self.df)):
current_numbers = set([self.df.iloc[i]['Z1'], self.df.iloc[i]['Z2'],
self.df.iloc[i]['Z3'], self.df.iloc[i]['Z4'],
self.df.iloc[i]['Z5']])
for j in range(1, look_back + 1):
prev_numbers = set([self.df.iloc[i-j]['Z1'], self.df.iloc[i-j]['Z2'],
self.df.iloc[i-j]['Z3'], self.df.iloc[i-j]['Z4'],
self.df.iloc[i-j]['Z5']])
for prev_num in prev_numbers:
for curr_num in current_numbers:
self.sequential_dependencies[f"lag_{j}"][f"{prev_num}_{curr_num}"] += 1
print(f"🔗 Sequenzielle Muster für {look_back} Ziehungen analysiert")
def _perform_cycle_analysis(self, max_cycle_length=15):
"""Analysiert zyklische Muster (NEU!)"""
print(f"\n🔄 ZYKLUS-ANALYSE")
pattern_sequence = []
for _, row in self.df.iterrows():
numbers = sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']])
pattern = self._get_pattern(numbers)
pattern_sequence.append(pattern)
# Zyklen erkennen
self.cycle_patterns = {}
for cycle_length in range(3, max_cycle_length + 1):
cycles = self._find_pattern_cycles(pattern_sequence, cycle_length)
if cycles:
self.cycle_patterns[cycle_length] = cycles
cycle_count = sum(len(cycles) for cycles in self.cycle_patterns.values())
print(f"🔄 {cycle_count} zyklische Muster erkannt")
def _generate_trend_predictions(self):
"""Generiert Trend-basierte Vorhersagen (NEU!)"""
print(f"\n🎯 TREND-VORHERSAGEN GENERIEREN")
for number in range(1, 51):
if number in self.momentum_scores:
momentum_data = self.momentum_scores[number]
# Multi-Faktor-Vorhersage-Score
momentum_weight = momentum_data['momentum_score'] * 0.4
frequency_weight = (self.number_frequencies[number] / len(self.df)) * 0.3
trend_weight = max(0, momentum_data['trend_score']) * 0.3
prediction_score = momentum_weight + frequency_weight + trend_weight
self.trend_predictions[number] = {
'prediction_score': prediction_score,
'recommendation': self._get_prediction_recommendation(prediction_score),
'confidence': self._get_confidence_level(prediction_score)
}
print(f"🎯 Trend-Vorhersagen für alle 50 Zahlen generiert")
def _calculate_trend_score(self, sequence):
"""Berechnet Trend-Score für eine Zahlensequenz."""
if len(sequence) < 2:
return 0
x = np.arange(len(sequence))
y = np.array(sequence)
weights = np.exp(x / len(x)) # Neuere Ziehungen wichtiger
try:
coeffs = np.polyfit(x, y, 1, w=weights)
return coeffs[0] # Steigung = Trend
except:
return 0
def _calculate_recency_score(self, sequence):
"""Berechnet Recency-Score."""
try:
last_hit_index = len(sequence) - 1 - sequence[::-1].index(1)
recency = 1 - (len(sequence) - 1 - last_hit_index) / len(sequence)
return recency
except ValueError:
return 0
def _get_momentum_status(self, score):
"""Klassifiziert Momentum-Status."""
if score > 0.5:
return "🔥 SEHR HEISS"
elif score > 0.35:
return "🌡️ HEISS"
elif score > 0.2:
return "😐 WARM"
elif score > 0.1:
return "🧊 KÜHL"
else:
return "❄️ EISKALT"
def _get_prediction_recommendation(self, score):
"""Empfehlung basierend auf Vorhersage-Score."""
if score > 0.4:
return "SEHR EMPFOHLEN"
elif score > 0.25:
return "EMPFOHLEN"
elif score > 0.15:
return "NEUTRAL"
else:
return "VERMEIDEN"
def _get_confidence_level(self, score):
"""Konfidenz-Level für Vorhersagen."""
if score > 0.4:
return "HOCH"
elif score > 0.25:
return "MITTEL"
else:
return "NIEDRIG"
def _find_pattern_cycles(self, sequence, cycle_length):
"""Findet zyklische Muster."""
cycle_patterns = defaultdict(list)
for i in range(len(sequence) - cycle_length):
pattern = ''.join(sequence[i:i+cycle_length])
cycle_patterns[pattern].append(i)
return {pattern: positions for pattern, positions in cycle_patterns.items()
if len(positions) >= 2}
def _get_pattern(self, numbers):
"""Bestimmt N/M/H-Muster."""
pattern = []
for num in numbers:
if 1 <= num <= 15:
pattern.append('N')
elif 16 <= num <= 35:
pattern.append('M')
else:
pattern.append('H')
return ''.join(pattern)
def _print_ultimate_analysis_summary(self):
"""Gibt detaillierte Analyse-Zusammenfassung aus."""
print(f"\n📈 ULTIMATE ANALYSE-ZUSAMMENFASSUNG:")
print("=" * 55)
# Top Trend-Empfehlungen
print("\n🎯 TOP 10 TREND-EMPFEHLUNGEN:")
top_predictions = sorted(self.trend_predictions.items(),
key=lambda x: x[1]['prediction_score'], reverse=True)[:10]
for i, (number, data) in enumerate(top_predictions):
momentum_status = self.momentum_scores[number]['status']
print(f"{i+1:2}. Zahl {number:2}: Score {data['prediction_score']:.3f} "
f"({data['recommendation']}) {momentum_status}")
# Top Muster mit Trend-Integration
print(f"\n🎨 TOP MUSTER (kombiniert mit Trends):")
for pattern, count in self.pattern_frequencies.most_common(5):
percentage = (count / len(self.drawn_combinations)) * 100
print(f" {pattern}: {count}x ({percentage:.1f}%)")
# Zyklische Erkenntnisse
if self.cycle_patterns:
print(f"\n🔄 ERKANNTE ZYKLEN:")
total_cycles = sum(len(cycles) for cycles in self.cycle_patterns.values())
print(f" Insgesamt {total_cycles} zyklische Muster erkannt")
def generate_ultimate_combination(self):
"""Generiert ultimativ optimierte Kombination mit allen Methoden."""
max_attempts = 1000
for attempt in range(max_attempts):
numbers = []
# Strategie-Mix basierend auf Trends:
# 40% Top-Trend-Zahlen, 30% Heiße Zahlen, 20% Position-optimiert, 10% Balance
# 2 Zahlen aus Top-Trend-Empfehlungen (40%)
top_trend_numbers = [num for num, data in sorted(self.trend_predictions.items(),
key=lambda x: x[1]['prediction_score'], reverse=True)[:15]
if data['recommendation'] in ['SEHR EMPFOHLEN', 'EMPFOHLEN']]
if len(top_trend_numbers) >= 2:
trend_picks = random.sample(top_trend_numbers[:10], 2)
numbers.extend(trend_picks)
# 2 Zahlen aus heißen Zahlen (30%)
if len(self.hot_numbers) >= 2:
remaining_hot = [n for n in self.hot_numbers if n not in numbers]
if len(remaining_hot) >= 2:
hot_picks = random.sample(remaining_hot[:8], min(2, len(remaining_hot)))
numbers.extend(hot_picks)
# 1 Zahl positions-optimiert oder warm (30%)
remaining_slots = 5 - len(numbers)
if remaining_slots > 0:
if self.warm_numbers:
remaining_warm = [n for n in self.warm_numbers if n not in numbers]
if remaining_warm:
warm_pick = random.choice(remaining_warm[:5])
numbers.append(warm_pick)
# Auffüllen bis 5 Zahlen
while len(numbers) < 5:
available_numbers = [n for n in range(1, 51) if n not in numbers]
# Gewichtete Auswahl basierend auf Trend-Scores
weights = [self.trend_predictions[n]['prediction_score'] for n in available_numbers]
if sum(weights) > 0:
additional_number = random.choices(available_numbers, weights=weights)[0]
else:
additional_number = random.choice(available_numbers)
numbers.append(additional_number)
# Sortieren und validieren
numbers = sorted(numbers[:5])
if self._validate_ultimate_combination(numbers):
return numbers
# Fallback
return self._generate_fallback_combination()
def _validate_ultimate_combination(self, numbers):
"""Erweiterte Validierung mit Trend-Kriterien."""
# Basis-Validierung
if tuple(numbers) in self.drawn_combinations:
return False
if len(set(numbers)) != 5:
return False
# Trend-Validierung
hot_count = sum(1 for n in numbers if n in self.hot_numbers)
high_trend_count = sum(1 for n in numbers
if self.trend_predictions[n]['recommendation'] == 'SEHR EMPFOHLEN')
# Mindestens 1 heiße oder 1 sehr empfohlene Zahl
if hot_count == 0 and high_trend_count == 0:
return False
# Standard-Validierungen
distances = [numbers[i+1] - numbers[i] for i in range(4)]
if min(distances) < 2 or max(distances) > 18:
return False
even_count = sum(1 for n in numbers if n % 2 == 0)
if even_count == 0 or even_count == 5:
return False
total = sum(numbers)
if total < 80 or total > 170:
return False
return True
def _generate_fallback_combination(self):
"""Fallback mit Trend-Integration."""
numbers = []
# Basis: NMMHH mit Trend-Gewichtung
ranges = {
'N': [n for n in range(1, 16) if n in self.hot_numbers + self.warm_numbers] or list(range(1, 16)),
'M': [n for n in range(16, 36) if n in self.hot_numbers + self.warm_numbers] or list(range(16, 36)),
'H': [n for n in range(36, 51) if n in self.hot_numbers + self.warm_numbers] or list(range(36, 51))
}
numbers.extend(random.sample(ranges['N'][:10], 1))
numbers.extend(random.sample(ranges['M'][:15], 2))
numbers.extend(random.sample(ranges['H'][:10], 2))
return sorted(numbers)
def get_optimized_supernumbers(self):
"""Trend-optimierte Superzahlen-Auswahl."""
# Integration von Trend-Daten für Superzahlen
sz1_trends = {}
sz2_trends = {}
# Letzte 10 Ziehungen analysieren
recent_df = self.df.tail(10)
for sz1 in range(1, 13): # Eurojackpot SZ1: 1-12
recent_count = (recent_df['SZ1'] == sz1).sum()
total_count = self.supernumber_frequencies['sz1'][sz1]
trend_score = (recent_count / 10) * 0.6 + (total_count / len(self.df)) * 0.4
sz1_trends[sz1] = trend_score
for sz2 in range(1, 11): # Eurojackpot SZ2: 1-10
recent_count = (recent_df['SZ2'] == sz2).sum()
total_count = self.supernumber_frequencies['sz2'][sz2]
trend_score = (recent_count / 10) * 0.6 + (total_count / len(self.df)) * 0.4
sz2_trends[sz2] = trend_score
# Gewichtete Auswahl
sz1_candidates = list(sz1_trends.keys())
sz1_weights = list(sz1_trends.values())
sz1 = random.choices(sz1_candidates, weights=sz1_weights)[0]
sz2_candidates = list(sz2_trends.keys())
sz2_weights = list(sz2_trends.values())
sz2 = random.choices(sz2_candidates, weights=sz2_weights)[0]
return sz1, sz2
def generate_ultimate_tips(self, num_tips=10):
"""Generiert ultimative Tipps mit kompletter Multi-Trend-Integration."""
print(f"\n🚀 ULTIMATE TIPP-GENERIERUNG")
print("=" * 50)
print(f"🎯 Kombiniert ALLE Optimierungsstrategien:")
print(f" ✅ Historische Häufigkeitsanalyse")
print(f" ✅ Positionsbasierte Gewichtung")
print(f" ✅ Multi-Ziehungs-Momentum-Analyse")
print(f" ✅ Sequenzielle Abhängigkeiten")
print(f" ✅ Zyklische Muster-Erkennung")
print(f" ✅ Trend-Vorhersage-Algorithmus")
generated_tips = []
strategy_distribution = Counter()
print(f"\n🎲 GENERIERE {num_tips} ULTIMATE TIPPS:")
print("=" * 60)
print(f"{'Nr':<3} {'Zahlen':<20} {'Muster':<7} {'🔥':<3} {'🎯':<3} {'Status'}")
print("-" * 60)
attempts = 0
max_attempts = num_tips * 50
while len(generated_tips) < num_tips and attempts < max_attempts:
attempts += 1
combination = self.generate_ultimate_combination()
if combination and tuple(combination) not in [tuple(tip['zahlen']) for tip in generated_tips]:
pattern = self._get_pattern(combination)
# Trend-Analyse des Tipps
hot_count = sum(1 for n in combination if n in self.hot_numbers)
trend_count = sum(1 for n in combination
if self.trend_predictions[n]['recommendation'] in ['SEHR EMPFOHLEN', 'EMPFOHLEN'])
# Superzahlen
sz1, sz2 = self.get_optimized_supernumbers()
# Strategie-Klassifikation
if hot_count >= 3:
strategy = "🔥 MOMENTUM"
elif trend_count >= 3:
strategy = "🎯 TREND"
elif pattern in ['NMMHH', 'MNMHH', 'NHMHM']:
strategy = "🎨 MUSTER"
else:
strategy = "⚖️ BALANCE"
strategy_distribution[strategy] += 1
tip = {
'tipp_nr': len(generated_tips) + 1,
'zahlen': combination,
'z1': combination[0],
'z2': combination[1],
'z3': combination[2],
'z4': combination[3],
'z5': combination[4],
'sz1': sz1,
'sz2': sz2,
'muster': pattern,
'summe': sum(combination),
'hot_count': hot_count,
'trend_count': trend_count,
'strategy': strategy
}
generated_tips.append(tip)
# Status ausgeben
zahlen_str = f"{combination[0]:2}-{combination[1]:2}-{combination[2]:2}-{combination[3]:2}-{combination[4]:2}"
print(f"{len(generated_tips):2}. {zahlen_str:<20} {pattern:<7} {hot_count:<3} {trend_count:<3} {strategy}")
# Ultimate Zusammenfassung
print(f"\n🏆 ULTIMATE OPTIMIERUNGS-ZUSAMMENFASSUNG:")
print("=" * 50)
print(f"{len(generated_tips)} Ultimate Tipps generiert")
print(f"🎯 Erfolgsrate: {(len(generated_tips)/attempts)*100:.1f}%")
print(f"📊 Durchschnitt {sum(tip['hot_count'] for tip in generated_tips)/len(generated_tips):.1f} heiße Zahlen pro Tipp")
print(f"🔮 Durchschnitt {sum(tip['trend_count'] for tip in generated_tips)/len(generated_tips):.1f} Trend-Zahlen pro Tipp")
# Strategie-Verteilung
print(f"\n📈 STRATEGIE-VERTEILUNG:")
for strategy, count in strategy_distribution.most_common():
print(f" {strategy}: {count} Tipps")
# Komplette Tipp-Ausgabe
print(f"\n🎯 ULTIMATE TIPP-EMPFEHLUNGEN:")
print("=" * 70)
print(f"{'Nr':<3} {'Hauptzahlen':<20} {'SZ1':<4} {'SZ2':<4} {'Muster':<7} {'Strategie':<12} {'Score'}")
print("-" * 70)
for tip in generated_tips:
zahlen_str = f"{tip['z1']:2}-{tip['z2']:2}-{tip['z3']:2}-{tip['z4']:2}-{tip['z5']:2}"
# Ultimate Score berechnen
ultimate_score = (tip['hot_count'] * 0.3 + tip['trend_count'] * 0.4 +
(5 if tip['muster'] in ['NMMHH', 'MNMHH'] else 3) * 0.3)
print(f"{tip['tipp_nr']:2}. {zahlen_str:<20} {tip['sz1']:<4} {tip['sz2']:<4} "
f"{tip['muster']:<7} {tip['strategy']:<12} {ultimate_score:.1f}")
# Export mit Ultimate Features
self._export_ultimate_tips(generated_tips)
return generated_tips
def _export_ultimate_tips(self, tips):
"""Exportiert Ultimate Tipps mit erweiterten Daten."""
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = f"/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/ultimate_tipps_{timestamp}.csv"
# Erweiterte Daten für Export
export_data = []
for tip in tips:
tip_data = tip.copy()
# Zusätzliche Trend-Daten hinzufügen
tip_data['trend_scores'] = [self.trend_predictions[n]['prediction_score']
for n in tip['zahlen']]
tip_data['avg_trend_score'] = np.mean(tip_data['trend_scores'])
tip_data['momentum_ratings'] = [self.momentum_scores[n]['status']
for n in tip['zahlen']]
export_data.append(tip_data)
tips_df = pd.DataFrame(export_data)
tips_df.to_csv(output_file, sep=';', index=False)
print(f"\n💾 ULTIMATE EXPORT:")
print("=" * 25)
print(f"✅ Ultimate Tipps gespeichert: ultimate_tipps_{timestamp}.csv")
print(f"🚀 Multi-Trend-Analyse integriert")
print(f"🎯 Höchste Optimierungsstufe erreicht")
print(f"📊 Erweiterte Trend-Daten enthalten")
def main():
"""Hauptfunktion für Ultimate Generator."""
print("🚀 ULTIMATE EUROJACKPOT GENERATOR")
print("🎯 Mit Multi-Ziehungs-Trend-Integration")
print("=" * 50)
# Generator initialisieren (lädt und analysiert automatisch alle Daten)
generator = UltimativerEurojackpotGenerator()
# Ultimate Tipps generieren
tips = generator.generate_ultimate_tips(10)
print(f"\n🏆 ULTIMATE OPTIMIERUNG ABGESCHLOSSEN!")
print("=" * 45)
print(f"🚀 10 Ultimate Tipps mit Multi-Trend-Analyse generiert")
print(f"📈 Maximale Trefferwahrscheinlichkeit durch:")
print(f" • Momentum-Analyse über 15 Ziehungen")
print(f" • Sequenzielle Abhängigkeiten")
print(f" • Zyklische Muster-Erkennung")
print(f" • Positionsbasierte Optimierung")
print(f" • Trend-Vorhersage-Algorithmus")
print(f"🍀 Viel Erfolg bei der nächsten Ziehung!")
# Zusätzliche Ultimate Insights
print(f"\n💡 ULTIMATE INSIGHTS:")
print("=" * 30)
# Top 5 Trend-Zahlen für nächste Ziehung
top_trend_numbers = sorted(generator.trend_predictions.items(),
key=lambda x: x[1]['prediction_score'], reverse=True)[:5]
print(f"🎯 TOP 5 TREND-ZAHLEN für nächste Ziehung:")
for i, (number, data) in enumerate(top_trend_numbers):
momentum_status = generator.momentum_scores[number]['status']
print(f" {i+1}. Zahl {number:2}: {data['recommendation']} {momentum_status}")
# Empfohlene Muster basierend auf Zyklen
if generator.cycle_patterns:
print(f"\n🔄 ZYKLUS-EMPFEHLUNG:")
# Finde das wahrscheinlichste nächste Muster basierend auf Zyklen
recent_patterns = []
for _, row in generator.df.tail(5).iterrows():
numbers = sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']])
pattern = generator._get_pattern(numbers)
recent_patterns.append(pattern)
print(f" Letzte 5 Muster: {''.join(recent_patterns)}")
# Empfehlung basierend auf häufigsten Mustern
top_pattern = generator.pattern_frequencies.most_common(1)[0]
print(f" Empfohlenes Muster: {top_pattern[0]} ({(top_pattern[1]/len(generator.df))*100:.1f}% Erfolgsrate)")
# Momentum-Warnung
very_hot = [n for n in generator.hot_numbers
if generator.momentum_scores[n]['momentum_score'] > 0.5]
if very_hot:
print(f"\n🔥 MOMENTUM-ALERT:")
print(f" SEHR HEIßE Zahlen: {very_hot[:5]}")
print(f" → Mindestens 1-2 dieser Zahlen in Tipps verwenden!")
return tips
# Zusätzliche Utility-Funktionen für erweiterte Analyse
def analyze_tip_quality(generator, tip_numbers):
"""Analysiert die Qualität eines einzelnen Tipps."""
quality_score = 0
analysis = {}
# Momentum-Analyse
hot_count = sum(1 for n in tip_numbers if n in generator.hot_numbers)
analysis['hot_numbers'] = hot_count
quality_score += hot_count * 0.2
# Trend-Analyse
trend_scores = [generator.trend_predictions[n]['prediction_score'] for n in tip_numbers]
avg_trend = np.mean(trend_scores)
analysis['avg_trend_score'] = avg_trend
quality_score += avg_trend * 0.3
# Positions-Analyse
position_quality = 0
for i, num in enumerate(sorted(tip_numbers)):
pos_freq = generator.position_frequencies[f'pos_{i+1}'][num]
if pos_freq > 0:
position_quality += pos_freq
analysis['position_quality'] = position_quality
quality_score += (position_quality / len(generator.df)) * 0.2
# Muster-Analyse
pattern = generator._get_pattern(sorted(tip_numbers))
pattern_freq = generator.pattern_frequencies[pattern]
pattern_score = pattern_freq / len(generator.df)
analysis['pattern'] = pattern
analysis['pattern_score'] = pattern_score
quality_score += pattern_score * 0.3
analysis['total_quality_score'] = quality_score
analysis['quality_rating'] = get_quality_rating(quality_score)
return analysis
def get_quality_rating(score):
"""Konvertiert Quality-Score in Rating."""
if score > 0.8:
return "🏆 PREMIUM"
elif score > 0.6:
return "🥇 SEHR GUT"
elif score > 0.4:
return "🥈 GUT"
elif score > 0.2:
return "🥉 DURCHSCHNITT"
else:
return "⚠️ SCHWACH"
def predict_jackpot_probability(generator, tip_numbers):
"""Schätzt Jackpot-Wahrscheinlichkeit basierend auf Trends."""
base_probability = 1 / 139838160 # Mathematische Grundwahrscheinlichkeit
# Trend-Multiplikator berechnen
trend_multiplier = 1.0
for number in tip_numbers:
momentum_score = generator.momentum_scores[number]['momentum_score']
trend_score = generator.trend_predictions[number]['prediction_score']
# Zahlen mit hohem Momentum/Trend erhöhen die relative Wahrscheinlichkeit
number_multiplier = 1 + (momentum_score * 0.1) + (trend_score * 0.15)
trend_multiplier *= number_multiplier
# Pattern-Bonus
pattern = generator._get_pattern(sorted(tip_numbers))
pattern_frequency = generator.pattern_frequencies[pattern] / len(generator.df)
pattern_multiplier = 1 + (pattern_frequency * 0.2)
estimated_probability = base_probability * trend_multiplier * pattern_multiplier
return {
'base_probability': base_probability,
'trend_multiplier': trend_multiplier,
'pattern_multiplier': pattern_multiplier,
'estimated_probability': estimated_probability,
'improvement_factor': (estimated_probability / base_probability)
}
def export_detailed_analysis(generator, tips, filename_suffix="detailed"):
"""Exportiert detaillierte Analyse aller Tipps."""
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = f"/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/analysis_{filename_suffix}_{timestamp}.csv"
detailed_data = []
for tip in tips:
tip_analysis = analyze_tip_quality(generator, tip['zahlen'])
probability_analysis = predict_jackpot_probability(generator, tip['zahlen'])
detailed_entry = {
**tip,
**tip_analysis,
**probability_analysis,
'individual_momentum_scores': [generator.momentum_scores[n]['momentum_score'] for n in tip['zahlen']],
'individual_trend_scores': [generator.trend_predictions[n]['prediction_score'] for n in tip['zahlen']],
'number_frequencies': [generator.number_frequencies[n] for n in tip['zahlen']]
}
detailed_data.append(detailed_entry)
# DataFrame erstellen und exportieren
df_detailed = pd.DataFrame(detailed_data)
df_detailed.to_csv(output_file, sep=';', index=False)
print(f"\n📊 DETAILLIERTE ANALYSE EXPORTIERT:")
print(f" 📁 Datei: analysis_{filename_suffix}_{timestamp}.csv")
print(f" 📈 Enthält Quality-Scores, Trend-Analysen und Wahrscheinlichkeits-Schätzungen")
if __name__ == "__main__":
# Reproduzierbarer Zufallsseed
random.seed(42)
np.random.seed(42)
# Ultimate Generator starten
tips = main()
# Optional: Detaillierte Analyse exportieren
if tips:
print(f"\n📊 ERWEITERTE ANALYSE VERFÜGBAR:")
print("=" * 40)
# Beispiel: Analysiere ersten Tipp detailliert
if len(tips) > 0:
generator = UltimativerEurojackpotGenerator()
sample_tip = tips[0]['zahlen']
quality_analysis = analyze_tip_quality(generator, sample_tip)
probability_analysis = predict_jackpot_probability(generator, sample_tip)
print(f"\n🔍 BEISPIEL-ANALYSE für Tipp 1 ({sample_tip}):")
print(f" 🏆 Quality-Rating: {quality_analysis['quality_rating']}")
print(f" 📈 Quality-Score: {quality_analysis['total_quality_score']:.3f}")
print(f" 🔥 Heiße Zahlen: {quality_analysis['hot_numbers']}/5")
print(f" 🎯 Avg. Trend-Score: {quality_analysis['avg_trend_score']:.3f}")
print(f" 🎨 Muster: {quality_analysis['pattern']} (Score: {quality_analysis['pattern_score']:.3f})")
print(f" 📊 Verbesserungs-Faktor: {probability_analysis['improvement_factor']:.2f}x")
# Optional: Detaillierte Analyse aller Tipps exportieren
export_detailed_analysis(generator, tips)
-234
View File
@@ -1,234 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Tipp-Generator für NMMHH-Muster
Generiert 10 Tipp-Felder basierend auf dem erfolgreichsten NMMHH-Muster,
die keine bereits gezogenen Kombinationen enthalten.
"""
import pandas as pd
import random
from itertools import combinations
def load_drawn_numbers():
"""Lädt alle bereits gezogenen Kombinationen."""
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleEurojackpotzahlen.csv", sep=';')
drawn_combinations = set()
for _, row in df.iterrows():
# Sortierte Kombination für Vergleich
combo = tuple(sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']]))
drawn_combinations.add(combo)
print(f"🚫 {len(drawn_combinations)} bereits gezogene Kombinationen geladen")
return drawn_combinations
def generate_nmmhh_numbers():
"""Generiert Zahlen nach dem NMMHH-Muster."""
# Bereichsdefinition basierend auf umschlüsselter Analyse
ranges = {
'N': list(range(1, 16)), # Niedrig: Gruppen 1-3 (Zahlen 1-15)
'M': list(range(16, 36)), # Mittel: Gruppen 4-7 (Zahlen 16-35)
'H': list(range(36, 51)) # Hoch: Gruppen 8-10 (Zahlen 36-50)
}
# NMMHH-Muster: 1 Niedrig, 2 Mittel, 2 Hoch
selected_numbers = []
# 1 Niedrige Zahl (Position z1)
selected_numbers.extend(random.sample(ranges['N'], 1))
# 2 Mittlere Zahlen (Positionen z2, z3)
selected_numbers.extend(random.sample(ranges['M'], 2))
# 2 Hohe Zahlen (Positionen z4, z5)
selected_numbers.extend(random.sample(ranges['H'], 2))
# Sortieren für Eurojackpot-Format
return sorted(selected_numbers)
def generate_optimized_nmmhh_numbers():
"""Generiert optimierte NMMHH-Zahlen basierend auf Positionsanalyse."""
# Optimierte Bereiche basierend auf Treffer-Analyse
optimized_ranges = {
'z1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], # Niedrig (sehr wahrscheinlich)
'z2': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25], # Niedrig-Mittel
'z3': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35], # Mittel
'z4': [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], # Mittel-Hoch
'z5': [41, 42, 43, 44, 45, 46, 47, 48, 49, 50] # Hoch (sehr wahrscheinlich)
}
selected_numbers = []
# Position z1: Niedrig
selected_numbers.append(random.choice(optimized_ranges['z1'][:10])) # Fokus auf 1-10
# Position z2: Niedrig-Mittel
selected_numbers.append(random.choice(optimized_ranges['z2'][5:])) # Fokus auf 16-25
# Position z3: Mittel
selected_numbers.append(random.choice(optimized_ranges['z3'])) # 21-35
# Position z4: Mittel-Hoch
selected_numbers.append(random.choice(optimized_ranges['z4'][5:])) # Fokus auf 36-45
# Position z5: Hoch
selected_numbers.append(random.choice(optimized_ranges['z5'])) # 41-50
# Duplikate vermeiden und sortieren
selected_numbers = list(set(selected_numbers))
# Falls durch Duplikat-Entfernung weniger als 5 Zahlen
while len(selected_numbers) < 5:
all_available = list(range(1, 51))
missing_number = random.choice([n for n in all_available if n not in selected_numbers])
selected_numbers.append(missing_number)
return sorted(selected_numbers[:5])
def generate_tips_nmmhh(num_tips=10):
"""Generiert Tipps basierend auf NMMHH-Muster ohne bereits gezogene Kombinationen."""
print("🎯 EUROJACKPOT TIPP-GENERATOR (NMMHH-MUSTER)")
print("="*50)
# Bereits gezogene Kombinationen laden
drawn_combinations = load_drawn_numbers()
# Häufigste Zahlen pro Position aus der Analyse
frequent_numbers = {
'z1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
'z2': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
'z3': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35],
'z4': [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45],
'z5': [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
}
print(f"\n📋 NMMHH-MUSTER BEDEUTUNG:")
print("N = Niedrig (1-15), M = Mittel (16-35), H = Hoch (36-50)")
print("Muster: 1 Niedrig + 2 Mittel + 2 Hoch = 14.7% Erfolgsrate!")
generated_tips = []
attempts = 0
max_attempts = 10000
print(f"\n🎲 GENERIERE {num_tips} OPTIMIERTE TIPPS:")
print("="*40)
while len(generated_tips) < num_tips and attempts < max_attempts:
attempts += 1
# Verschiedene Generierungsstrategien abwechseln
if attempts % 3 == 0:
tip = generate_optimized_nmmhh_numbers()
else:
tip = generate_nmmhh_numbers()
# Prüfen ob bereits gezogen
tip_tuple = tuple(sorted(tip))
if tip_tuple not in drawn_combinations and tip not in generated_tips:
generated_tips.append(tip)
# Muster-Verifikation
pattern = []
for num in tip:
if 1 <= num <= 15:
pattern.append('N')
elif 16 <= num <= 35:
pattern.append('M')
else:
pattern.append('H')
pattern_str = ''.join(pattern)
print(f"Tipp {len(generated_tips):2}: {tip[0]:2}-{tip[1]:2}-{tip[2]:2}-{tip[3]:2}-{tip[4]:2} (Muster: {pattern_str})")
if len(generated_tips) < num_tips:
print(f"\n⚠️ Nur {len(generated_tips)} von {num_tips} Tipps generiert nach {attempts} Versuchen")
else:
print(f"\n✅ Alle {num_tips} Tipps erfolgreich generiert!")
print(f"\n📊 MUSTER-ANALYSE DER GENERIERTEN TIPPS:")
print("="*45)
pattern_counts = {}
for tip in generated_tips:
pattern = []
for num in tip:
if 1 <= num <= 15:
pattern.append('N')
elif 16 <= num <= 35:
pattern.append('M')
else:
pattern.append('H')
pattern_str = ''.join(pattern)
pattern_counts[pattern_str] = pattern_counts.get(pattern_str, 0) + 1
for pattern, count in sorted(pattern_counts.items(), key=lambda x: x[1], reverse=True):
print(f"Muster {pattern}: {count} Tipps")
# Zusätzliche Superzahlen-Empfehlungen
print(f"\n🎲 SUPERZAHLEN-EMPFEHLUNGEN:")
print("="*30)
# Lade Superzahlen-Statistiken
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleEurojackpotzahlen.csv", sep=';')
sz1_counts = df['SZ1'].value_counts().head(5)
sz2_counts = df['SZ2'].value_counts().head(5)
print(f"Top 5 SZ1: {list(sz1_counts.index)}")
print(f"Top 5 SZ2: {list(sz2_counts.index)}")
# Empfohlene Superzahlen für die Tipps
recommended_sz1 = list(sz1_counts.index)[:3]
recommended_sz2 = list(sz2_counts.index)[:3]
print(f"\n🎯 KOMPLETTE TIPP-EMPFEHLUNGEN:")
print("="*40)
print(f"{'Tipp':<5} {'Hauptzahlen':<20} {'SZ1':<4} {'SZ2':<4}")
print("-" * 40)
final_tips = []
for i, tip in enumerate(generated_tips, 1):
sz1 = random.choice(recommended_sz1)
sz2 = random.choice(recommended_sz2)
tip_str = f"{tip[0]:2}-{tip[1]:2}-{tip[2]:2}-{tip[3]:2}-{tip[4]:2}"
print(f"{i:2}. {tip_str:<20} {sz1:<4} {sz2:<4}")
final_tips.append({
'tipp_nr': i,
'z1': tip[0],
'z2': tip[1],
'z3': tip[2],
'z4': tip[3],
'z5': tip[4],
'sz1': sz1,
'sz2': sz2,
'muster': ''.join(['N' if n <= 15 else 'M' if n <= 35 else 'H' for n in tip])
})
# Export der Tipps
print(f"\n💾 TIPPS EXPORTIEREN:")
print("="*25)
tips_df = pd.DataFrame(final_tips)
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/eurojackpot_tipps_nmmhh.csv"
tips_df.to_csv(output_file, sep=';', index=False)
print(f"✅ 10 Tipps gespeichert: eurojackpot_tipps_nmmhh.csv")
print(f"📈 Basierend auf NMMHH-Muster mit 14.7% historischer Erfolgsrate")
print(f"🚫 Keine bereits gezogenen Kombinationen enthalten")
return final_tips
if __name__ == "__main__":
# Zufallsseed für reproduzierbare Ergebnisse (optional)
random.seed(42)
tips = generate_tips_nmmhh(10)
@@ -1,234 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Tipp-Generator für NMMHH-Muster
Generiert 10 Tipp-Felder basierend auf dem erfolgreichsten NMMHH-Muster,
die keine bereits gezogenen Kombinationen enthalten.
"""
import pandas as pd
import random
from itertools import combinations
def load_drawn_numbers():
"""Lädt alle bereits gezogenen Kombinationen."""
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleEurojackpotzahlen.csv", sep=';')
drawn_combinations = set()
for _, row in df.iterrows():
# Sortierte Kombination für Vergleich
combo = tuple(sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']]))
drawn_combinations.add(combo)
print(f"🚫 {len(drawn_combinations)} bereits gezogene Kombinationen geladen")
return drawn_combinations
def generate_nmmhh_numbers():
"""Generiert Zahlen nach dem NMMHH-Muster."""
# Bereichsdefinition basierend auf umschlüsselter Analyse
ranges = {
'N': list(range(1, 16)), # Niedrig: Gruppen 1-3 (Zahlen 1-15)
'M': list(range(16, 36)), # Mittel: Gruppen 4-7 (Zahlen 16-35)
'H': list(range(36, 51)) # Hoch: Gruppen 8-10 (Zahlen 36-50)
}
# NMMHH-Muster: 1 Niedrig, 2 Mittel, 2 Hoch
selected_numbers = []
# 1 Niedrige Zahl (Position z1)
selected_numbers.extend(random.sample(ranges['N'], 1))
# 2 Mittlere Zahlen (Positionen z2, z3)
selected_numbers.extend(random.sample(ranges['M'], 2))
# 2 Hohe Zahlen (Positionen z4, z5)
selected_numbers.extend(random.sample(ranges['H'], 2))
# Sortieren für Eurojackpot-Format
return sorted(selected_numbers)
def generate_optimized_nmmhh_numbers():
"""Generiert optimierte NMMHH-Zahlen basierend auf Positionsanalyse."""
# Optimierte Bereiche basierend auf Treffer-Analyse
optimized_ranges = {
'z1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], # Niedrig (sehr wahrscheinlich)
'z2': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25], # Niedrig-Mittel
'z3': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35], # Mittel
'z4': [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], # Mittel-Hoch
'z5': [41, 42, 43, 44, 45, 46, 47, 48, 49, 50] # Hoch (sehr wahrscheinlich)
}
selected_numbers = []
# Position z1: Niedrig
selected_numbers.append(random.choice(optimized_ranges['z1'][:10])) # Fokus auf 1-10
# Position z2: Niedrig-Mittel
selected_numbers.append(random.choice(optimized_ranges['z2'][5:])) # Fokus auf 16-25
# Position z3: Mittel
selected_numbers.append(random.choice(optimized_ranges['z3'])) # 21-35
# Position z4: Mittel-Hoch
selected_numbers.append(random.choice(optimized_ranges['z4'][5:])) # Fokus auf 36-45
# Position z5: Hoch
selected_numbers.append(random.choice(optimized_ranges['z5'])) # 41-50
# Duplikate vermeiden und sortieren
selected_numbers = list(set(selected_numbers))
# Falls durch Duplikat-Entfernung weniger als 5 Zahlen
while len(selected_numbers) < 5:
all_available = list(range(1, 51))
missing_number = random.choice([n for n in all_available if n not in selected_numbers])
selected_numbers.append(missing_number)
return sorted(selected_numbers[:5])
def generate_tips_nmmhh(num_tips=10):
"""Generiert Tipps basierend auf NMMHH-Muster ohne bereits gezogene Kombinationen."""
print("🎯 EUROJACKPOT TIPP-GENERATOR (NMMHH-MUSTER)")
print("="*50)
# Bereits gezogene Kombinationen laden
drawn_combinations = load_drawn_numbers()
# Häufigste Zahlen pro Position aus der Analyse
frequent_numbers = {
'z1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
'z2': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
'z3': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35],
'z4': [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45],
'z5': [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
}
print(f"\n📋 NMMHH-MUSTER BEDEUTUNG:")
print("N = Niedrig (1-15), M = Mittel (16-35), H = Hoch (36-50)")
print("Muster: 1 Niedrig + 2 Mittel + 2 Hoch = 14.7% Erfolgsrate!")
generated_tips = []
attempts = 0
max_attempts = 10000
print(f"\n🎲 GENERIERE {num_tips} OPTIMIERTE TIPPS:")
print("="*40)
while len(generated_tips) < num_tips and attempts < max_attempts:
attempts += 1
# Verschiedene Generierungsstrategien abwechseln
if attempts % 3 == 0:
tip = generate_optimized_nmmhh_numbers()
else:
tip = generate_nmmhh_numbers()
# Prüfen ob bereits gezogen
tip_tuple = tuple(sorted(tip))
if tip_tuple not in drawn_combinations and tip not in generated_tips:
generated_tips.append(tip)
# Muster-Verifikation
pattern = []
for num in tip:
if 1 <= num <= 15:
pattern.append('N')
elif 16 <= num <= 35:
pattern.append('M')
else:
pattern.append('H')
pattern_str = ''.join(pattern)
print(f"Tipp {len(generated_tips):2}: {tip[0]:2}-{tip[1]:2}-{tip[2]:2}-{tip[3]:2}-{tip[4]:2} (Muster: {pattern_str})")
if len(generated_tips) < num_tips:
print(f"\n⚠️ Nur {len(generated_tips)} von {num_tips} Tipps generiert nach {attempts} Versuchen")
else:
print(f"\n✅ Alle {num_tips} Tipps erfolgreich generiert!")
print(f"\n📊 MUSTER-ANALYSE DER GENERIERTEN TIPPS:")
print("="*45)
pattern_counts = {}
for tip in generated_tips:
pattern = []
for num in tip:
if 1 <= num <= 15:
pattern.append('N')
elif 16 <= num <= 35:
pattern.append('M')
else:
pattern.append('H')
pattern_str = ''.join(pattern)
pattern_counts[pattern_str] = pattern_counts.get(pattern_str, 0) + 1
for pattern, count in sorted(pattern_counts.items(), key=lambda x: x[1], reverse=True):
print(f"Muster {pattern}: {count} Tipps")
# Zusätzliche Superzahlen-Empfehlungen
print(f"\n🎲 SUPERZAHLEN-EMPFEHLUNGEN:")
print("="*30)
# Lade Superzahlen-Statistiken
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleEurojackpotzahlen.csv", sep=';')
sz1_counts = df['SZ1'].value_counts().head(5)
sz2_counts = df['SZ2'].value_counts().head(5)
print(f"Top 5 SZ1: {list(sz1_counts.index)}")
print(f"Top 5 SZ2: {list(sz2_counts.index)}")
# Empfohlene Superzahlen für die Tipps
recommended_sz1 = list(sz1_counts.index)[:3]
recommended_sz2 = list(sz2_counts.index)[:3]
print(f"\n🎯 KOMPLETTE TIPP-EMPFEHLUNGEN:")
print("="*40)
print(f"{'Tipp':<5} {'Hauptzahlen':<20} {'SZ1':<4} {'SZ2':<4}")
print("-" * 40)
final_tips = []
for i, tip in enumerate(generated_tips, 1):
sz1 = random.choice(recommended_sz1)
sz2 = random.choice(recommended_sz2)
tip_str = f"{tip[0]:2}-{tip[1]:2}-{tip[2]:2}-{tip[3]:2}-{tip[4]:2}"
print(f"{i:2}. {tip_str:<20} {sz1:<4} {sz2:<4}")
final_tips.append({
'tipp_nr': i,
'z1': tip[0],
'z2': tip[1],
'z3': tip[2],
'z4': tip[3],
'z5': tip[4],
'sz1': sz1,
'sz2': sz2,
'muster': ''.join(['N' if n <= 15 else 'M' if n <= 35 else 'H' for n in tip])
})
# Export der Tipps
print(f"\n💾 TIPPS EXPORTIEREN:")
print("="*25)
tips_df = pd.DataFrame(final_tips)
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/eurojackpot_tipps_nmmhh.csv"
tips_df.to_csv(output_file, sep=';', index=False)
print(f"✅ 10 Tipps gespeichert: eurojackpot_tipps_nmmhh.csv")
print(f"📈 Basierend auf NMMHH-Muster mit 14.7% historischer Erfolgsrate")
print(f"🚫 Keine bereits gezogenen Kombinationen enthalten")
return final_tips
if __name__ == "__main__":
# Zufallsseed für reproduzierbare Ergebnisse (optional)
random.seed(42)
tips = generate_tips_nmmhh(10)
File diff suppressed because it is too large Load Diff
-77
View File
@@ -1,77 +0,0 @@
#!/usr/bin/env python3
"""
Erstellt Beispiel-CSV-Dateien für das Eurojackpot-Processing
"""
import pandas as pd
import itertools
from datetime import datetime, timedelta
import random
def create_all_combinations():
"""Erstellt eine CSV mit allen möglichen 5-aus-50 Kombinationen (Beispiel mit ersten 100)."""
print("Erstelle Beispiel-Kombinationsdatei...")
# Für Demo: nur erste 100 Kombinationen von 5 aus 20 Zahlen
# (Vollständige 5-aus-50 Kombinationen wären über 2 Millionen!)
combinations = []
count = 0
for combo in itertools.combinations(range(1, 21), 5): # 5 aus 20 für Demo
combinations.append({
'Zahl1': combo[0],
'Zahl2': combo[1],
'Zahl3': combo[2],
'Zahl4': combo[3],
'Zahl5': combo[4]
})
count += 1
if count >= 100: # Limitierung für Demo
break
df = pd.DataFrame(combinations)
df.to_csv('alle_kombinationen_beispiel.csv', index=False)
print(f"Beispiel-Kombinationsdatei erstellt: {len(df)} Kombinationen")
return df
def create_drawn_numbers():
"""Erstellt eine CSV mit gezogenen Zahlen (Beispieldaten)."""
print("Erstelle Beispiel-Datei mit gezogenen Zahlen...")
drawn_numbers = []
start_date = datetime(2023, 1, 1)
# 20 zufällige Ziehungen erstellen
for i in range(20):
date = start_date + timedelta(days=i*7) # Wöchentliche Ziehungen
# 5 zufällige Zahlen zwischen 1 und 20 (ohne Wiederholung)
numbers = sorted(random.sample(range(1, 21), 5))
drawn_numbers.append({
'Datum': date.strftime('%Y-%m-%d'),
'Z1': numbers[0],
'Z2': numbers[1],
'Z3': numbers[2],
'Z4': numbers[3],
'Z5': numbers[4]
})
df = pd.DataFrame(drawn_numbers)
df.to_csv('gezogene_zahlen_beispiel.csv', index=False)
print(f"Beispiel-Datei mit gezogenen Zahlen erstellt: {len(df)} Ziehungen")
return df
if __name__ == "__main__":
print("=== Erstelle Beispiel-CSV-Dateien ===\n")
# Seed für reproduzierbare Ergebnisse
random.seed(42)
combinations_df = create_all_combinations()
drawn_df = create_drawn_numbers()
print("\n=== Beispieldateien erstellt ===")
print("- alle_kombinationen_beispiel.csv")
print("- gezogene_zahlen_beispiel.csv")
print("\nSie können jetzt das Hauptscript testen:")
-165
View File
@@ -1,165 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot CSV Processor
Dieses Script liest zwei CSV-Dateien ein:
1. Alle möglichen Zahlenkombinationen (5 Zahlen)
2. Bereits gezogene Zahlen mit Datumsstempel
Es markiert in der ersten Datei alle bereits gezogenen Kombinationen mit 1 (sonst 0).
"""
import pandas as pd
import sys
from pathlib import Path
def load_combinations_file(filepath):
"""Lädt die Datei mit allen möglichen Kombinationen."""
try:
df = pd.read_csv(filepath)
print(f"Kombinationen geladen: {len(df)} Zeilen")
print(f"Spalten: {list(df.columns)}")
return df
except Exception as e:
print(f"Fehler beim Laden der Kombinationsdatei: {e}")
return None
def load_drawn_numbers_file(filepath):
"""Lädt die Datei mit bereits gezogenen Zahlen."""
try:
df = pd.read_csv(filepath)
print(f"Gezogene Zahlen geladen: {len(df)} Zeilen")
print(f"Spalten: {list(df.columns)}")
return df
except Exception as e:
print(f"Fehler beim Laden der gezogenen Zahlen: {e}")
return None
def create_combination_key(row, z_columns):
"""Erstellt einen eindeutigen Schlüssel aus den 5 Zahlen (sortiert)."""
numbers = [row[col] for col in z_columns]
return tuple(sorted(numbers))
def process_eurojackpot_data(combinations_file, drawn_numbers_file, output_file):
"""Hauptfunktion zur Verarbeitung der Eurojackpot-Daten."""
# CSV-Dateien laden
print("Lade Kombinationsdatei...")
combinations_df = load_combinations_file(combinations_file)
if combinations_df is None:
return False
print("\nLade Datei mit gezogenen Zahlen...")
drawn_df = load_drawn_numbers_file(drawn_numbers_file)
if drawn_df is None:
return False
# Spalten für Zahlen identifizieren
# Annahme: In der Kombinationsdatei sind die ersten 5 Spalten die Zahlen
# In der gezogenen Zahlen-Datei sind es Z1, Z2, Z3, Z4, Z5
# Für Kombinationsdatei - erste 5 numerische Spalten verwenden
numeric_cols = combinations_df.select_dtypes(include=['number']).columns
if len(numeric_cols) >= 5:
combo_z_columns = numeric_cols[:5].tolist()
else:
# Fallback: erste 5 Spalten nehmen
combo_z_columns = combinations_df.columns[:5].tolist()
print(f"Verwendete Spalten für Kombinationen: {combo_z_columns}")
# Für gezogene Zahlen - Z1 bis Z5 Spalten suchen
z_columns = [col for col in drawn_df.columns if col.startswith('Z') and col[1:].isdigit()]
z_columns = sorted(z_columns)[:5] # Ersten 5 Z-Spalten nehmen
if not z_columns:
# Fallback: nach Spalten mit "Zahl" im Namen suchen oder numerische Spalten
z_columns = [col for col in drawn_df.columns if 'zahl' in col.lower()][:5]
if not z_columns:
z_columns = drawn_df.select_dtypes(include=['number']).columns[:5].tolist()
print(f"Verwendete Spalten für gezogene Zahlen: {z_columns}")
# Set mit allen gezogenen Kombinationen erstellen
print("\nErstelle Set mit gezogenen Kombinationen...")
drawn_combinations = set()
for _, row in drawn_df.iterrows():
combo_key = create_combination_key(row, z_columns)
drawn_combinations.add(combo_key)
print(f"Anzahl eindeutige gezogene Kombinationen: {len(drawn_combinations)}")
# Neue Spalte für Markierungen hinzufügen
print("\nMarkiere gezogene Kombinationen...")
combinations_df['bereits_gezogen'] = 0
marked_count = 0
for idx, row in combinations_df.iterrows():
combo_key = create_combination_key(row, combo_z_columns)
if combo_key in drawn_combinations:
combinations_df.at[idx, 'bereits_gezogen'] = 1
marked_count += 1
print(f"Anzahl markierte Kombinationen: {marked_count}")
# Ergebnis speichern
print(f"\nSpeichere Ergebnis in: {output_file}")
combinations_df.to_csv(output_file, index=False)
# Statistiken ausgeben
total_combinations = len(combinations_df)
drawn_percentage = (marked_count / total_combinations) * 100 if total_combinations > 0 else 0
print(f"\n=== STATISTIKEN ===")
print(f"Gesamte Kombinationen: {total_combinations:,}")
print(f"Bereits gezogene Kombinationen: {marked_count:,}")
print(f"Prozentsatz bereits gezogen: {drawn_percentage:.4f}%")
print(f"Noch nicht gezogene Kombinationen: {total_combinations - marked_count:,}")
return True
def main():
"""Hauptfunktion mit Benutzerinteraktion."""
print("=== Eurojackpot CSV Processor ===\n")
# Dateipfade abfragen oder Standard verwenden
if len(sys.argv) >= 4:
combinations_file = sys.argv[1]
drawn_numbers_file = sys.argv[2]
output_file = sys.argv[3]
else:
print("Geben Sie die Dateipfade ein (oder drücken Sie Enter für Standard):")
combinations_file = input("Pfad zur Kombinationsdatei (alle_kombinationen.csv): ").strip()
if not combinations_file:
combinations_file = "alle_kombinationen.csv"
drawn_numbers_file = input("Pfad zur Datei mit gezogenen Zahlen (gezogene_zahlen.csv): ").strip()
if not drawn_numbers_file:
drawn_numbers_file = "gezogene_zahlen.csv"
output_file = input("Pfad für Ausgabedatei (kombinationen_markiert.csv): ").strip()
if not output_file:
output_file = "kombinationen_markiert.csv"
# Überprüfen ob Dateien existieren
if not Path(combinations_file).exists():
print(f"Fehler: Kombinationsdatei '{combinations_file}' nicht gefunden!")
return
if not Path(drawn_numbers_file).exists():
print(f"Fehler: Datei mit gezogenen Zahlen '{drawn_numbers_file}' nicht gefunden!")
return
# Verarbeitung starten
success = process_eurojackpot_data(combinations_file, drawn_numbers_file, output_file)
if success:
print(f"\n✅ Verarbeitung erfolgreich abgeschlossen!")
print(f"Ergebnis gespeichert in: {output_file}")
else:
print("\n❌ Fehler bei der Verarbeitung!")
if __name__ == "__main__":
main()
@@ -1,220 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot CSV Processor - Angepasst für Semikolon-getrennte CSV-Dateien
Dieses Script liest zwei CSV-Dateien ein:
1. Alle möglichen Zahlenkombinationen (5 Zahlen)
2. Bereits gezogene Zahlen mit Datumsstempel
Es markiert in der ersten Datei alle bereits gezogenen Kombinationen mit 1 (sonst 0).
"""
import pandas as pd
import sys
from pathlib import Path
def detect_separator(filepath):
"""Erkennt das CSV-Trennzeichen automatisch."""
try:
with open(filepath, 'r', encoding='utf-8') as f:
first_line = f.readline()
if ';' in first_line and first_line.count(';') > first_line.count(','):
return ';'
return ','
except:
return ','
def load_combinations_file(filepath):
"""Lädt die Datei mit allen möglichen Kombinationen."""
try:
sep = detect_separator(filepath)
print(f"Erkanntes Trennzeichen für Kombinationen: '{sep}'")
df = pd.read_csv(filepath, sep=sep)
print(f"Kombinationen geladen: {len(df)} Zeilen")
print(f"Spalten: {list(df.columns)}")
return df
except Exception as e:
print(f"Fehler beim Laden der Kombinationsdatei: {e}")
return None
def load_drawn_numbers_file(filepath):
"""Lädt die Datei mit bereits gezogenen Zahlen."""
try:
sep = detect_separator(filepath)
print(f"Erkanntes Trennzeichen für gezogene Zahlen: '{sep}'")
df = pd.read_csv(filepath, sep=sep)
print(f"Gezogene Zahlen geladen: {len(df)} Zeilen")
print(f"Spalten: {list(df.columns)}")
return df
except Exception as e:
print(f"Fehler beim Laden der gezogenen Zahlen: {e}")
return None
def identify_number_columns(df, is_combinations=True):
"""Identifiziert die Spalten mit den Zahlen."""
columns = df.columns.tolist()
if is_combinations:
# Für Kombinationsdatei: Z1, Z2, Z3, Z4, Z5 suchen
z_cols = [col for col in columns if col.startswith('Z') and len(col) == 2 and col[1:].isdigit()]
z_cols = sorted(z_cols)[:5]
if len(z_cols) >= 5:
return z_cols
# Fallback: erste 5 numerische Spalten
numeric_cols = df.select_dtypes(include=['number']).columns[:5].tolist()
if len(numeric_cols) >= 5:
return numeric_cols
# Fallback: erste 5 Spalten
return columns[:5]
else:
# Für gezogene Zahlen: Z1-Z5 suchen (nicht SZ1, SZ2)
z_cols = [col for col in columns if col.startswith('Z') and len(col) == 2 and col[1:].isdigit()]
z_cols = [col for col in z_cols if not col.startswith('SZ')] # Superzahlen ausschließen
z_cols = sorted(z_cols)[:5]
if len(z_cols) >= 5:
return z_cols
# Fallback: numerische Spalten (ohne Datum)
numeric_cols = df.select_dtypes(include=['number']).columns
numeric_cols = [col for col in numeric_cols if 'datum' not in col.lower()][:5]
if len(numeric_cols) >= 5:
return numeric_cols.tolist()
# Letzter Fallback
return columns[:5]
def create_combination_key(row, z_columns):
"""Erstellt einen eindeutigen Schlüssel aus den 5 Zahlen (sortiert)."""
try:
numbers = [int(row[col]) for col in z_columns]
return tuple(sorted(numbers))
except:
return None
def process_eurojackpot_data(combinations_file, drawn_numbers_file, output_file):
"""Hauptfunktion zur Verarbeitung der Eurojackpot-Daten."""
# CSV-Dateien laden
print("Lade Kombinationsdatei...")
combinations_df = load_combinations_file(combinations_file)
if combinations_df is None:
return False
print("\nLade Datei mit gezogenen Zahlen...")
drawn_df = load_drawn_numbers_file(drawn_numbers_file)
if drawn_df is None:
return False
# Spalten für Zahlen identifizieren
combo_z_columns = identify_number_columns(combinations_df, is_combinations=True)
drawn_z_columns = identify_number_columns(drawn_df, is_combinations=False)
print(f"\nVerwendete Spalten für Kombinationen: {combo_z_columns}")
print(f"Verwendete Spalten für gezogene Zahlen: {drawn_z_columns}")
# Datencheck
print(f"\nErste Kombination: {combinations_df[combo_z_columns].iloc[0].tolist()}")
print(f"Erste gezogene Zahlen: {drawn_df[drawn_z_columns].iloc[0].tolist()}")
# Set mit allen gezogenen Kombinationen erstellen
print("\nErstelle Set mit gezogenen Kombinationen...")
drawn_combinations = set()
for _, row in drawn_df.iterrows():
combo_key = create_combination_key(row, drawn_z_columns)
if combo_key:
drawn_combinations.add(combo_key)
print(f"Anzahl eindeutige gezogene Kombinationen: {len(drawn_combinations)}")
# Beispiele anzeigen
if drawn_combinations:
print(f"Erste 5 gezogene Kombinationen: {list(drawn_combinations)[:5]}")
# Neue Spalte für Markierungen hinzufügen (falls noch nicht vorhanden)
if 'bereits_gezogen' not in combinations_df.columns:
combinations_df['bereits_gezogen'] = 0
else:
combinations_df['bereits_gezogen'] = 0 # Zurücksetzen
print("\nMarkiere gezogene Kombinationen...")
marked_count = 0
for idx, row in combinations_df.iterrows():
combo_key = create_combination_key(row, combo_z_columns)
if combo_key and combo_key in drawn_combinations:
combinations_df.at[idx, 'bereits_gezogen'] = 1
marked_count += 1
if marked_count <= 5: # Erste 5 Treffer anzeigen
print(f"Treffer gefunden: {combo_key}")
print(f"Anzahl markierte Kombinationen: {marked_count}")
# Ergebnis speichern
print(f"\nSpeichere Ergebnis in: {output_file}")
sep = detect_separator(combinations_file) # Gleiches Trennzeichen wie Eingabe verwenden
combinations_df.to_csv(output_file, sep=sep, index=False)
# Statistiken ausgeben
total_combinations = len(combinations_df)
drawn_percentage = (marked_count / total_combinations) * 100 if total_combinations > 0 else 0
print(f"\n=== STATISTIKEN ===")
print(f"Gesamte Kombinationen: {total_combinations:,}")
print(f"Bereits gezogene Kombinationen: {marked_count:,}")
print(f"Prozentsatz bereits gezogen: {drawn_percentage:.4f}%")
print(f"Noch nicht gezogene Kombinationen: {total_combinations - marked_count:,}")
return True
def main():
"""Hauptfunktion mit Benutzerinteraktion."""
print("=== Eurojackpot CSV Processor (Fixed) ===\n")
# Dateipfade abfragen oder Standard verwenden
if len(sys.argv) >= 4:
combinations_file = sys.argv[1]
drawn_numbers_file = sys.argv[2]
output_file = sys.argv[3]
else:
print("Geben Sie die Dateipfade ein (oder drücken Sie Enter für Standard):")
combinations_file = input("Pfad zur Kombinationsdatei: ").strip()
if not combinations_file:
combinations_file = "Alle_Eurojackpot_Kombinationen_mit_Status.csv"
drawn_numbers_file = input("Pfad zur Datei mit gezogenen Zahlen: ").strip()
if not drawn_numbers_file:
drawn_numbers_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv"
output_file = input("Pfad für Ausgabedatei: ").strip()
if not output_file:
output_file = "Kombinationen_markiert_fixed.csv"
# Überprüfen ob Dateien existieren
if not Path(combinations_file).exists():
print(f"Fehler: Kombinationsdatei '{combinations_file}' nicht gefunden!")
return
if not Path(drawn_numbers_file).exists():
print(f"Fehler: Datei mit gezogenen Zahlen '{drawn_numbers_file}' nicht gefunden!")
return
# Verarbeitung starten
success = process_eurojackpot_data(combinations_file, drawn_numbers_file, output_file)
if success:
print(f"\n✅ Verarbeitung erfolgreich abgeschlossen!")
print(f"Ergebnis gespeichert in: {output_file}")
else:
print("\n❌ Fehler bei der Verarbeitung!")
if __name__ == "__main__":
main()
-62
View File
@@ -1,62 +0,0 @@
#!/usr/bin/env python3
"""
Vereinfachte Version des Eurojackpot Processors
Für spezifische Spaltenstrukturen
"""
import pandas as pd
def process_eurojackpot_simple(combinations_csv, drawn_numbers_csv, output_csv):
"""
Vereinfachte Verarbeitung mit festen Spaltenstrukturen
Parameter:
- combinations_csv: CSV mit allen Kombinationen (Spalten: Zahl1, Zahl2, Zahl3, Zahl4, Zahl5)
- drawn_numbers_csv: CSV mit gezogenen Zahlen (Spalten: Datum, Z1, Z2, Z3, Z4, Z5)
- output_csv: Ausgabedatei
"""
# Dateien laden
print("Lade Kombinationsdatei...")
combinations = pd.read_csv(combinations_csv)
print("Lade gezogene Zahlen...")
drawn = pd.read_csv(drawn_numbers_csv)
# Gezogene Kombinationen als Set erstellen (sortiert für Vergleich)
drawn_sets = set()
for _, row in drawn.iterrows():
# Annahme: Spalten Z1, Z2, Z3, Z4, Z5 enthalten die Zahlen
numbers = sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5']])
drawn_sets.add(tuple(numbers))
print(f"Gefundene gezogene Kombinationen: {len(drawn_sets)}")
# Neue Spalte hinzufügen
combinations['bereits_gezogen'] = 0
# Jede Kombination prüfen
marked = 0
for idx, row in combinations.iterrows():
# Annahme: erste 5 Spalten enthalten die Zahlenkombination
combo_cols = combinations.columns[:5]
numbers = sorted([row[col] for col in combo_cols])
if tuple(numbers) in drawn_sets:
combinations.at[idx, 'bereits_gezogen'] = 1
marked += 1
# Ergebnis speichern
combinations.to_csv(output_csv, index=False)
print(f"Verarbeitung abgeschlossen!")
print(f"Markierte Kombinationen: {marked}")
print(f"Ergebnis gespeichert in: {output_csv}")
# Beispielaufruf
if __name__ == "__main__":
process_eurojackpot_simple(
"alle_kombinationen.csv",
"gezogene_zahlen.csv",
"kombinationen_markiert.csv"
)
-681
View File
@@ -1,681 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Historical Data Updater
Lädt automatisch die neuesten Eurojackpot-Ziehungen von der offiziellen Website
und aktualisiert die lokale CSV-Datei.
Quellen:
- https://www.eurojackpot.de/de/eurojackpot/gewinnzahlen.html
- Oder alternative APIs/Websites
Features:
- Automatisches Scraping der neuesten Ziehungen
- Duplikate-Vermeidung
- Backup vor Update
- Validierung der neuen Daten
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import shutil
import os
import re
from typing import List, Dict, Optional
import time
class EurojackpotDataUpdater:
"""Aktualisiert historische Eurojackpot-Daten automatisch."""
def __init__(self, data_file: str):
"""
Initialisiert den Updater.
Args:
data_file: Pfad zur lokalen CSV-Datei
"""
self.data_file = data_file
self.backup_file = None
self.df_existing = None
# API/Scraping URLs
self.sources = {
'eurojackpot_de': 'https://www.eurojackpot.de/de/eurojackpot/gewinnzahlen.html',
'euro-jackpot_net': 'https://www.euro-jackpot.net/de/gewinnzahlen',
'lottode': 'https://www.lotto.de/eurojackpot/gewinnzahlen'
}
print("🔄 EUROJACKPOT DATA UPDATER")
print("=" * 60)
def load_existing_data(self) -> bool:
"""Lädt existierende Daten."""
try:
if not os.path.exists(self.data_file):
print(f"⚠️ Datei nicht gefunden: {self.data_file}")
print(" Erstelle neue Datei...")
self.df_existing = pd.DataFrame(columns=['datum', 'Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'SZ1', 'SZ2'])
return True
self.df_existing = pd.read_csv(self.data_file, sep=';')
# Datum als datetime
if 'datum' in self.df_existing.columns:
self.df_existing['datum'] = pd.to_datetime(
self.df_existing['datum'],
format='%Y-%m-%d',
errors='coerce'
)
print(f"✅ Existierende Daten geladen: {len(self.df_existing)} Ziehungen")
if len(self.df_existing) > 0:
latest = self.df_existing['datum'].max()
print(f" Neueste Ziehung: {latest.strftime('%Y-%m-%d') if pd.notna(latest) else 'Unbekannt'}")
return True
except Exception as e:
print(f"❌ Fehler beim Laden: {e}")
return False
def create_backup(self) -> bool:
"""Erstellt Backup der existierenden Datei."""
if not os.path.exists(self.data_file):
return True
try:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_dir = os.path.join(os.path.dirname(self.data_file), "backups")
os.makedirs(backup_dir, exist_ok=True)
filename = os.path.basename(self.data_file)
self.backup_file = os.path.join(backup_dir, f"{filename}.backup_{timestamp}")
shutil.copy2(self.data_file, self.backup_file)
print(f"✅ Backup erstellt: {os.path.basename(self.backup_file)}")
return True
except Exception as e:
print(f"⚠️ Backup-Fehler: {e}")
return False
def fetch_from_eurojackpot_de(self) -> List[Dict]:
"""
Scrapt Daten von eurojackpot.de
Returns:
Liste von Ziehungen als Dictionaries
"""
print("\n🌐 Versuche eurojackpot.de...")
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
}
response = requests.get(self.sources['eurojackpot_de'], headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.content, 'html.parser')
# Suche nach Ziehungsergebnissen
# Dies ist ein generisches Beispiel - muss an tatsächliche Website-Struktur angepasst werden
draws = []
# Beispiel-Parsing (muss angepasst werden!)
result_blocks = soup.find_all('div', class_='drawing-result')
for block in result_blocks[:10]: # Letzte 10 Ziehungen
try:
# Datum extrahieren
date_elem = block.find('span', class_='date')
if not date_elem:
continue
date_str = date_elem.text.strip()
date_obj = self._parse_german_date(date_str)
# Zahlen extrahieren
numbers = []
number_elems = block.find_all('span', class_='ball')
for num_elem in number_elems[:5]:
num = int(num_elem.text.strip())
numbers.append(num)
# Eurozahlen extrahieren
euro_numbers = []
euro_elems = block.find_all('span', class_='euro-ball')
for euro_elem in euro_elems[:2]:
euro_num = int(euro_elem.text.strip())
euro_numbers.append(euro_num)
if len(numbers) == 5 and len(euro_numbers) == 2:
draws.append({
'datum': date_obj,
'Z1': numbers[0],
'Z2': numbers[1],
'Z3': numbers[2],
'Z4': numbers[3],
'Z5': numbers[4],
'SZ1': euro_numbers[0],
'SZ2': euro_numbers[1]
})
except Exception as e:
continue
if draws:
print(f"{len(draws)} Ziehungen gefunden")
return draws
else:
print(" ⚠️ Keine Ziehungen gefunden (HTML-Struktur möglicherweise geändert)")
return []
except Exception as e:
print(f" ❌ Fehler: {e}")
return []
def fetch_from_euro_jackpot_net(self) -> List[Dict]:
"""
Scrapt Daten von euro-jackpot.net
Returns:
Liste von Ziehungen
"""
print("\n🌐 Versuche euro-jackpot.net...")
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
}
response = requests.get(self.sources['euro-jackpot_net'], headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.content, 'html.parser')
draws = []
# Parsing-Logik für diese Website
# (Platzhalter - muss an tatsächliche Struktur angepasst werden)
result_rows = soup.find_all('tr', class_='result-row')
for row in result_rows[:10]:
try:
cells = row.find_all('td')
if len(cells) < 8:
continue
# Datum
date_str = cells[0].text.strip()
date_obj = self._parse_german_date(date_str)
# Hauptzahlen
numbers = [int(cells[i].text.strip()) for i in range(1, 6)]
# Eurozahlen
euro_numbers = [int(cells[i].text.strip()) for i in range(6, 8)]
draws.append({
'datum': date_obj,
'Z1': numbers[0],
'Z2': numbers[1],
'Z3': numbers[2],
'Z4': numbers[3],
'Z5': numbers[4],
'SZ1': euro_numbers[0],
'SZ2': euro_numbers[1]
})
except Exception as e:
continue
if draws:
print(f"{len(draws)} Ziehungen gefunden")
else:
print(" ⚠️ Keine Ziehungen gefunden")
return draws
except Exception as e:
print(f" ❌ Fehler: {e}")
return []
def fetch_from_manual_input(self) -> List[Dict]:
"""
Manuelle Eingabe von neuen Ziehungen.
Returns:
Liste von Ziehungen
"""
print("\n⌨️ MANUELLE EINGABE")
print("=" * 60)
print("Gib die neuesten Ziehungen manuell ein.")
print("Format: YYYY-MM-DD Z1 Z2 Z3 Z4 Z5 SZ1 SZ2")
print("Beispiel: 2025-01-24 7 18 26 37 46 3 11")
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, 6)]
euro_numbers = [int(parts[i]) for i in range(6, 8)]
# Validierung
if not all(1 <= n <= 50 for n in numbers):
print(" ❌ Hauptzahlen müssen zwischen 1 und 50 liegen.")
continue
if not all(1 <= n <= 12 for n in euro_numbers):
print(" ❌ Eurozahlen müssen zwischen 1 und 12 liegen.")
continue
if len(set(numbers)) != 5:
print(" ❌ Hauptzahlen müssen eindeutig sein.")
continue
if len(set(euro_numbers)) != 2:
print(" ❌ Eurozahlen müssen eindeutig sein.")
continue
draws.append({
'datum': date_obj,
'Z1': numbers[0],
'Z2': numbers[1],
'Z3': numbers[2],
'Z4': numbers[3],
'Z5': numbers[4],
'SZ1': euro_numbers[0],
'SZ2': euro_numbers[1]
})
print(f" ✅ Ziehung hinzugefügt: {date_obj.strftime('%Y-%m-%d')}")
except ValueError as e:
print(f" ❌ Fehler: {e}")
continue
if draws:
print(f"\n{len(draws)} Ziehungen manuell eingegeben")
return draws
def _parse_german_date(self, date_str: str) -> datetime:
"""
Parst deutsches Datumsformat.
Args:
date_str: Datum als String (z.B. "24.01.2025" oder "24. Januar 2025")
Returns:
datetime Objekt
"""
# Entferne zusätzliche Leerzeichen
date_str = re.sub(r'\s+', ' ', date_str.strip())
# Monatsnamen-Mapping
months_de = {
'januar': 1, 'februar': 2, 'märz': 3, 'april': 4,
'mai': 5, 'juni': 6, 'juli': 7, 'august': 8,
'september': 9, 'oktober': 10, 'november': 11, 'dezember': 12
}
# Versuche verschiedene Formate
formats = [
'%d.%m.%Y',
'%d.%m.%y',
'%Y-%m-%d',
'%d/%m/%Y'
]
for fmt in formats:
try:
return datetime.strptime(date_str, fmt)
except ValueError:
continue
# Versuche mit Monatsnamen
for month_name, month_num in months_de.items():
if month_name.lower() in date_str.lower():
# Extrahiere Tag und Jahr
match = re.search(r'(\d{1,2})\.?\s+' + month_name + r'\s+(\d{4})', date_str, re.IGNORECASE)
if match:
day = int(match.group(1))
year = int(match.group(2))
return datetime(year, month_num, day)
# Fallback: aktuelles Datum
print(f" ⚠️ Konnte Datum nicht parsen: {date_str}, nutze aktuelles Datum")
return datetime.now()
def fetch_new_draws(self, source: str = 'auto') -> List[Dict]:
"""
Holt neue Ziehungen von der gewählten Quelle.
Args:
source: 'auto', 'eurojackpot_de', 'euro_jackpot_net', 'manual'
Returns:
Liste von neuen Ziehungen
"""
print(f"\n🔍 SUCHE NACH NEUEN ZIEHUNGEN (Quelle: {source})")
print("=" * 60)
all_draws = []
if source == 'auto':
# Versuche alle Quellen
sources_to_try = [
('eurojackpot_de', self.fetch_from_eurojackpot_de),
('euro_jackpot_net', self.fetch_from_euro_jackpot_net)
]
for source_name, fetch_func in sources_to_try:
draws = fetch_func()
if draws:
all_draws.extend(draws)
break # Erste erfolgreiche Quelle nutzen
time.sleep(1) # Pause zwischen Requests
if not all_draws:
print("\n⚠️ Automatisches Scraping fehlgeschlagen.")
print(" Möchtest du Daten manuell eingeben? (j/n): ", end='')
if input().lower() in ['j', 'ja', 'y', 'yes']:
all_draws = self.fetch_from_manual_input()
elif source == 'eurojackpot_de':
all_draws = self.fetch_from_eurojackpot_de()
elif source == 'euro_jackpot_net':
all_draws = self.fetch_from_euro_jackpot_net()
elif source == 'manual':
all_draws = self.fetch_from_manual_input()
else:
print(f"❌ Unbekannte Quelle: {source}")
return all_draws
def validate_draw(self, draw: Dict) -> bool:
"""
Validiert eine Ziehung.
Args:
draw: Ziehungs-Dictionary
Returns:
True wenn valide
"""
try:
# Prüfe Pflichtfelder
required_fields = ['datum', 'Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'SZ1', 'SZ2']
if not all(field in draw for field in required_fields):
return False
# Prüfe Hauptzahlen (1-50)
main_numbers = [draw[f'Z{i}'] for i in range(1, 6)]
if not all(1 <= n <= 50 for n in main_numbers):
return False
if len(set(main_numbers)) != 5: # Eindeutig
return False
# Prüfe Eurozahlen (1-12)
euro_numbers = [draw['SZ1'], draw['SZ2']]
if not all(1 <= n <= 12 for n in euro_numbers):
return False
if len(set(euro_numbers)) != 2: # Eindeutig
return False
# Prüfe Datum
if not isinstance(draw['datum'], datetime):
return False
return True
except Exception:
return False
def merge_with_existing(self, new_draws: List[Dict]) -> pd.DataFrame:
"""
Merged neue Ziehungen mit existierenden Daten.
Args:
new_draws: Liste von neuen Ziehungen
Returns:
Zusammengeführter DataFrame
"""
print(f"\n🔀 MERGE MIT EXISTIERENDEN DATEN")
print("=" * 60)
# Validiere neue Ziehungen
valid_draws = [draw for draw in new_draws if self.validate_draw(draw)]
if len(valid_draws) < len(new_draws):
invalid_count = len(new_draws) - len(valid_draws)
print(f"⚠️ {invalid_count} ungültige Ziehung(en) übersprungen")
if not valid_draws:
print("❌ Keine gültigen neuen Ziehungen zum Hinzufügen")
return self.df_existing
# Erstelle DataFrame aus neuen Ziehungen
df_new = pd.DataFrame(valid_draws)
# Kombiniere
if self.df_existing is None or len(self.df_existing) == 0:
df_combined = df_new
else:
df_combined = pd.concat([self.df_existing, df_new], ignore_index=True)
# Entferne Duplikate (basierend auf Datum + Zahlen)
before_dedup = len(df_combined)
df_combined = df_combined.drop_duplicates(
subset=['datum', 'Z1', 'Z2', 'Z3', 'Z4', 'Z5'],
keep='first'
)
after_dedup = len(df_combined)
duplicates_removed = before_dedup - after_dedup
if duplicates_removed > 0:
print(f"🗑️ {duplicates_removed} Duplikat(e) entfernt")
# Sortiere nach Datum
df_combined = df_combined.sort_values('datum', ascending=True)
df_combined = df_combined.reset_index(drop=True)
# Berechne neue Einträge
new_entries = len(df_combined) - len(self.df_existing) if self.df_existing is not None else len(df_combined)
print(f"✅ Merge abgeschlossen:")
print(f" Vorher: {len(self.df_existing) if self.df_existing is not None else 0} Ziehungen")
print(f" Neu hinzugefügt: {new_entries} Ziehungen")
print(f" Nachher: {len(df_combined)} Ziehungen")
return df_combined
def save_updated_data(self, df: pd.DataFrame) -> bool:
"""
Speichert aktualisierte Daten.
Args:
df: DataFrame zum Speichern
Returns:
True bei Erfolg
"""
try:
# Format Datum als String
df_to_save = df.copy()
df_to_save['datum'] = df_to_save['datum'].dt.strftime('%Y-%m-%d')
# Speichern
df_to_save.to_csv(self.data_file, sep=';', index=False)
print(f"\n💾 Daten gespeichert: {self.data_file}")
print(f" {len(df)} Ziehungen total")
if len(df) > 0:
latest = df['datum'].max()
print(f" Neueste Ziehung: {latest.strftime('%Y-%m-%d')}")
return True
except Exception as e:
print(f"❌ Fehler beim Speichern: {e}")
# Restore backup
if self.backup_file and os.path.exists(self.backup_file):
print("🔄 Stelle Backup wieder her...")
shutil.copy2(self.backup_file, self.data_file)
print("✅ Backup wiederhergestellt")
return False
def update(self, source: str = 'auto', dry_run: bool = False) -> bool:
"""
Führt komplettes Update durch.
Args:
source: Datenquelle ('auto', 'eurojackpot_de', 'euro_jackpot_net', 'manual')
dry_run: Wenn True, keine Änderungen speichern
Returns:
True bei Erfolg
"""
print(f"\n{'🧪 DRY RUN MODE' if dry_run else '🚀 UPDATE STARTEN'}")
print("=" * 60)
# 1. Lade existierende Daten
if not self.load_existing_data():
return False
# 2. Backup erstellen
if not dry_run:
self.create_backup()
# 3. Hole neue Ziehungen
new_draws = self.fetch_new_draws(source=source)
if not new_draws:
print("\n✅ Keine neuen Ziehungen gefunden - Daten sind aktuell")
return True
# 4. Merge mit existierenden Daten
df_updated = self.merge_with_existing(new_draws)
# 5. Speichern
if not dry_run:
return self.save_updated_data(df_updated)
else:
print("\n🧪 DRY RUN - Keine Änderungen gespeichert")
print(f" Würde {len(df_updated)} Ziehungen speichern")
return True
def main():
"""Hauptfunktion für interaktive Nutzung."""
print("=" * 70)
print(" EUROJACKPOT HISTORICAL DATA UPDATER")
print("=" * 70)
print()
# Konfiguration
default_data_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv"
print("📁 KONFIGURATION")
print("=" * 60)
print(f"Standard-Datei: {default_data_file}")
print()
use_default = input("Standard-Datei verwenden? (j/n): ").lower().strip()
if use_default in ['j', 'ja', 'y', 'yes', '']:
data_file = default_data_file
else:
data_file = input("Pfad zur Datendatei: ").strip()
print()
print("🌐 DATENQUELLE WÄHLEN")
print("=" * 60)
print("1. Auto (versucht alle Quellen)")
print("2. eurojackpot.de")
print("3. euro-jackpot.net")
print("4. Manuelle Eingabe")
print()
source_choice = input("Wahl (1-4): ").strip()
source_map = {
'1': 'auto',
'2': 'eurojackpot_de',
'3': 'euro_jackpot_net',
'4': 'manual'
}
source = source_map.get(source_choice, 'auto')
print()
print("🧪 DRY RUN?")
print("=" * 60)
print("Dry Run = Keine Änderungen, nur Vorschau")
dry_run_choice = input("Dry Run aktivieren? (j/n): ").lower().strip()
dry_run = dry_run_choice in ['j', 'ja', 'y', 'yes']
print()
# Update durchführen
updater = EurojackpotDataUpdater(data_file)
success = updater.update(source=source, dry_run=dry_run)
print()
print("=" * 70)
if success:
print("✅ UPDATE ERFOLGREICH ABGESCHLOSSEN")
else:
print("❌ UPDATE FEHLGESCHLAGEN")
print("=" * 70)
return success
if __name__ == "__main__":
import sys
# Einfache CLI
if len(sys.argv) > 1:
# Kommandozeilen-Modus
data_file = sys.argv[1]
source = sys.argv[2] if len(sys.argv) > 2 else 'auto'
dry_run = '--dry-run' in sys.argv
updater = EurojackpotDataUpdater(data_file)
success = updater.update(source=source, dry_run=dry_run)
sys.exit(0 if success else 1)
else:
# Interaktiver Modus
main()
-210
View File
@@ -1,210 +0,0 @@
#!/usr/bin/env python3
"""
Eurojackpot Zahlen-Umschlüsselung
Fügt neue Spalten z1, z2, z3, z4, z5 hinzu mit umschlüsselten Werten:
1-5 → 1, 6-10 → 2, 11-15 → 3, 16-20 → 4, 21-25 → 5,
26-30 → 6, 31-35 → 7, 36-40 → 8, 41-45 → 9, 46-50 → 10
"""
import pandas as pd
def convert_number_to_group(number):
"""Konvertiert eine Zahl (1-50) in eine Gruppe (1-10)."""
if 1 <= number <= 5:
return 1
elif 6 <= number <= 10:
return 2
elif 11 <= number <= 15:
return 3
elif 16 <= number <= 20:
return 4
elif 21 <= number <= 25:
return 5
elif 26 <= number <= 30:
return 6
elif 31 <= number <= 35:
return 7
elif 36 <= number <= 40:
return 8
elif 41 <= number <= 45:
return 9
elif 46 <= number <= 50:
return 10
else:
return 0 # Fehlerfall
def process_number_conversion():
"""Führt die Zahlenumschlüsselung durch."""
# Eingabedatei laden
input_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/data/AlleEurojackpotzahlen.csv"
print("🔢 EUROJACKPOT ZAHLEN-UMSCHLÜSSELUNG")
print("="*50)
# Daten laden
print(f"📁 Lade Daten aus: AlleEurojackpotzahlen.csv")
df = pd.read_csv(input_file, sep=';')
print(f"{len(df)} Ziehungen geladen")
# Umschlüsselungsschema anzeigen
print(f"\n📋 UMSCHLÜSSELUNGSSCHEMA:")
print("="*30)
ranges = [
(1, 5, 1), (6, 10, 2), (11, 15, 3), (16, 20, 4), (21, 25, 5),
(26, 30, 6), (31, 35, 7), (36, 40, 8), (41, 45, 9), (46, 50, 10)
]
for start, end, group in ranges:
print(f"Zahlen {start:2}-{end:2} → Gruppe {group:2}")
# Neue Spalten erstellen
print(f"\n🔄 Erstelle neue Spalten z1, z2, z3, z4, z5...")
source_columns = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5']
target_columns = ['z1', 'z2', 'z3', 'z4', 'z5']
for source_col, target_col in zip(source_columns, target_columns):
df[target_col] = df[source_col].apply(convert_number_to_group)
print(f" {source_col}{target_col}")
# Erste 5 Beispiele anzeigen
print(f"\n📊 BEISPIEL-UMSCHLÜSSELUNGEN (erste 5 Ziehungen):")
print("="*60)
print(f"{'Datum':<12} {'Z1→z1':<8} {'Z2→z2':<8} {'Z3→z3':<8} {'Z4→z4':<8} {'Z5→z5':<8}")
print("-" * 60)
for i in range(min(5, len(df))):
row = df.iloc[i]
datum = row['datum']
conversions = []
for source_col, target_col in zip(source_columns, target_columns):
original = row[source_col]
converted = row[target_col]
conversions.append(f"{original:2}{converted}")
print(f"{datum:<12} {conversions[0]:<8} {conversions[1]:<8} {conversions[2]:<8} {conversions[3]:<8} {conversions[4]:<8}")
# Statistiken der Umschlüsselung
print(f"\n📈 STATISTIKEN DER UMSCHLÜSSELTEN WERTE:")
print("="*45)
# Häufigkeit der Gruppen über alle Positionen
all_converted_values = []
for target_col in target_columns:
all_converted_values.extend(df[target_col].tolist())
from collections import Counter
group_counts = Counter(all_converted_values)
print(f"Verteilung der Gruppen (1-10) über alle Positionen:")
total_values = len(all_converted_values)
for group in range(1, 11):
count = group_counts.get(group, 0)
percentage = (count / total_values) * 100
original_range = f"{(group-1)*5 + 1}-{group*5}"
print(f"Gruppe {group:2} ({original_range:5}): {count:4}x ({percentage:5.1f}%)")
# Statistiken pro Position
print(f"\n📊 VERTEILUNG PRO POSITION:")
print("="*35)
for i, target_col in enumerate(target_columns, 1):
position_counts = Counter(df[target_col])
print(f"\nPosition z{i} ({target_col}):")
for group in range(1, 11):
count = position_counts.get(group, 0)
percentage = (count / len(df)) * 100
print(f" Gruppe {group:2}: {count:3}x ({percentage:4.1f}%)")
# Häufigste Kombinationen der umschlüsselten Werte
print(f"\n🎯 HÄUFIGSTE KOMBINATIONEN (umschlüsselt):")
print("="*45)
# Kombinationen als Strings erstellen
df['kombination_umschluesselt'] = df.apply(
lambda row: f"{row['z1']}-{row['z2']}-{row['z3']}-{row['z4']}-{row['z5']}", axis=1
)
combination_counts = Counter(df['kombination_umschluesselt'])
print(f"Top 15 Kombinationen (z1-z2-z3-z4-z5):")
for i, (combination, count) in enumerate(combination_counts.most_common(15), 1):
percentage = (count / len(df)) * 100
print(f"{i:2}. {combination:15} {count:3}x ({percentage:4.1f}%)")
# Muster-Analyse
print(f"\n🔍 MUSTER-ANALYSE:")
print("="*25)
# Aufsteigende Kombinationen
ascending_count = 0
descending_count = 0
for _, row in df.iterrows():
values = [row[col] for col in target_columns]
if values == sorted(values):
ascending_count += 1
elif values == sorted(values, reverse=True):
descending_count += 1
print(f"Aufsteigende Kombinationen: {ascending_count} ({(ascending_count/len(df)*100):.1f}%)")
print(f"Absteigende Kombinationen: {descending_count} ({(descending_count/len(df)*100):.1f}%)")
# Gleiche Werte
same_values_stats = {}
for num_same in range(2, 6):
count = 0
for _, row in df.iterrows():
values = [row[col] for col in target_columns]
value_counts = Counter(values)
if max(value_counts.values()) >= num_same:
count += 1
same_values_stats[num_same] = count
print(f"Mindestens {num_same} gleiche Werte: {count} ({(count/len(df)*100):.1f}%)")
# Bereiche der umschlüsselten Werte
print(f"\n📋 BEREICHSANALYSE (umschlüsselt):")
print("="*35)
# Niedrig (1-3), Mittel (4-7), Hoch (8-10)
for i, target_col in enumerate(target_columns, 1):
low_count = sum(1 for val in df[target_col] if 1 <= val <= 3)
mid_count = sum(1 for val in df[target_col] if 4 <= val <= 7)
high_count = sum(1 for val in df[target_col] if 8 <= val <= 10)
low_pct = (low_count / len(df)) * 100
mid_pct = (mid_count / len(df)) * 100
high_pct = (high_count / len(df)) * 100
print(f"z{i}: Niedrig(1-3)={low_pct:4.1f}% | Mittel(4-7)={mid_pct:4.1f}% | Hoch(8-10)={high_pct:4.1f}%")
# Ausgabedatei speichern
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/AlleEurojackpotzahlen_umschluesselt.csv"
print(f"\n💾 DATEI SPEICHERN:")
print("="*25)
# Spalten neu ordnen (Original + neue Spalten)
column_order = ['tag', 'datum', 'Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'z1', 'z2', 'z3', 'z4', 'z5', 'SZ1', 'SZ2', 'kombination_umschluesselt']
# Prüfen welche Spalten existieren
available_columns = [col for col in column_order if col in df.columns]
df_output = df[available_columns]
df_output.to_csv(output_file, sep=';', index=False)
print(f"✅ Umschlüsselte Daten gespeichert: AlleEurojackpotzahlen_umschluesselt.csv")
print(f"📊 Anzahl Spalten: {len(df_output.columns)}")
print(f"📈 Anzahl Zeilen: {len(df_output)}")
print(f"\n🔍 NEUE SPALTEN:")
for col in ['z1', 'z2', 'z3', 'z4', 'z5', 'kombination_umschluesselt']:
if col in df_output.columns:
print(f"{col}")
return df_output
if __name__ == "__main__":
result_df = process_number_conversion()