Add misc scripts to repoitory
This commit is contained in:
@@ -6,7 +6,7 @@ Script to read and parse Powerball numbers from a CSV file.
|
||||
import csv
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List, Dict
|
||||
from typing import List, Dict, Tuple, Optional
|
||||
from collections import Counter
|
||||
|
||||
|
||||
@@ -85,7 +85,84 @@ def display_powerball_data(data: List[Dict]) -> None:
|
||||
print(f"{entry['date_str']:<12} {numbers_str:<30} {entry['multiplier']:<10}")
|
||||
|
||||
|
||||
def analyze_most_frequent_numbers(data: List[Dict]) -> None:
|
||||
def _get_unweighted_top_numbers(draws: List[Dict]) -> Tuple[List[int], Optional[int]]:
|
||||
"""Return top 5 white balls and top Powerball from a draw list."""
|
||||
if not draws:
|
||||
return [], None
|
||||
|
||||
white_counter = Counter()
|
||||
powerball_counter = Counter()
|
||||
|
||||
for entry in draws:
|
||||
numbers = entry['winning_numbers']
|
||||
for number in numbers[:5]:
|
||||
white_counter[number] += 1
|
||||
|
||||
if len(numbers) >= 6:
|
||||
powerball_counter[numbers[5]] += 1
|
||||
|
||||
top_white = [number for number, _ in white_counter.most_common(5)]
|
||||
top_powerball = powerball_counter.most_common(1)[0][0] if powerball_counter else None
|
||||
|
||||
return top_white, top_powerball
|
||||
|
||||
|
||||
def _get_recency_weighted_top_numbers(draws: List[Dict]) -> Tuple[List[int], Optional[int]]:
|
||||
"""Return top numbers weighted so newer draws contribute more."""
|
||||
if not draws:
|
||||
return [], None
|
||||
|
||||
sorted_draws = sorted(draws, key=lambda x: x['draw_date'])
|
||||
total_draws = len(sorted_draws)
|
||||
|
||||
white_scores = Counter()
|
||||
powerball_scores = Counter()
|
||||
|
||||
for index, entry in enumerate(sorted_draws, start=1):
|
||||
weight = index / total_draws
|
||||
numbers = entry['winning_numbers']
|
||||
|
||||
for number in numbers[:5]:
|
||||
white_scores[number] += weight
|
||||
|
||||
if len(numbers) >= 6:
|
||||
powerball_scores[numbers[5]] += weight
|
||||
|
||||
top_white = [number for number, _ in white_scores.most_common(5)]
|
||||
top_powerball = powerball_scores.most_common(1)[0][0] if powerball_scores else None
|
||||
|
||||
return top_white, top_powerball
|
||||
|
||||
|
||||
def _get_aggressive_recency_weighted_top_numbers(draws: List[Dict]) -> Tuple[List[int], Optional[int]]:
|
||||
"""Return top numbers with an aggressive recency curve (cubic weighting)."""
|
||||
if not draws:
|
||||
return [], None
|
||||
|
||||
sorted_draws = sorted(draws, key=lambda x: x['draw_date'])
|
||||
total_draws = len(sorted_draws)
|
||||
|
||||
white_scores = Counter()
|
||||
powerball_scores = Counter()
|
||||
|
||||
for index, entry in enumerate(sorted_draws, start=1):
|
||||
normalized_position = index / total_draws
|
||||
weight = normalized_position ** 3
|
||||
numbers = entry['winning_numbers']
|
||||
|
||||
for number in numbers[:5]:
|
||||
white_scores[number] += weight
|
||||
|
||||
if len(numbers) >= 6:
|
||||
powerball_scores[numbers[5]] += weight
|
||||
|
||||
top_white = [number for number, _ in white_scores.most_common(5)]
|
||||
top_powerball = powerball_scores.most_common(1)[0][0] if powerball_scores else None
|
||||
|
||||
return top_white, top_powerball
|
||||
|
||||
|
||||
def analyze_most_frequent_numbers(data: List[Dict]) -> Dict:
|
||||
"""
|
||||
Analyze and display the most frequent number in each slot position.
|
||||
|
||||
@@ -131,27 +208,51 @@ def analyze_most_frequent_numbers(data: List[Dict]) -> None:
|
||||
for i in range(min(5, num_positions)):
|
||||
first_five_combined.extend(position_numbers[i])
|
||||
|
||||
top_five_numbers = []
|
||||
top_ten_numbers = []
|
||||
if first_five_combined:
|
||||
counter_first_five = Counter(first_five_combined)
|
||||
top_five_numbers = counter_first_five.most_common(5)
|
||||
top_ten_numbers = counter_first_five.most_common(10)
|
||||
print("Top 5 most drawn numbers in first 5 positions combined:")
|
||||
for rank, (number, frequency) in enumerate(top_five_numbers, start=1):
|
||||
percentage = (frequency / len(first_five_combined)) * 100
|
||||
print(f" {rank}. {number:<3} (appears {frequency} times, {percentage:.1f}%)")
|
||||
|
||||
# Analyze the sixth position (Powerball)
|
||||
powerball_ranked = []
|
||||
most_common_sixth = None
|
||||
if num_positions >= 6:
|
||||
sixth_position_numbers = position_numbers[5]
|
||||
counter_sixth = Counter(sixth_position_numbers)
|
||||
powerball_ranked = counter_sixth.most_common(5)
|
||||
most_common_sixth, freq_sixth = counter_sixth.most_common(1)[0]
|
||||
percentage_sixth = (freq_sixth / len(sixth_position_numbers)) * 100
|
||||
print(f"\nMost drawn number in position 6 (Powerball): {most_common_sixth} (appears {freq_sixth} times, {percentage_sixth:.1f}%)")
|
||||
|
||||
# Third strategy: most frequent numbers from the most recent 104 draws
|
||||
sorted_by_date = sorted(data, key=lambda x: x['draw_date'])
|
||||
recent_104_draws = sorted_by_date[-104:]
|
||||
recent_104_top_five, recent_104_powerball = _get_unweighted_top_numbers(recent_104_draws)
|
||||
|
||||
# Fourth strategy: weighted-by-recency across all draws
|
||||
weighted_top_five, weighted_powerball = _get_recency_weighted_top_numbers(data)
|
||||
|
||||
# Fifth strategy: aggressive weighted-by-recency across all draws
|
||||
aggressive_weighted_top_five, aggressive_weighted_powerball = _get_aggressive_recency_weighted_top_numbers(data)
|
||||
|
||||
# Return statistics for prediction
|
||||
return {
|
||||
'top_five_combined': [num for num, freq in top_five_numbers] if first_five_combined else [],
|
||||
'most_common_powerball': most_common_sixth
|
||||
'top_ten_combined': [num for num, freq in top_ten_numbers],
|
||||
'most_common_powerball': most_common_sixth,
|
||||
'powerball_ranked': [num for num, freq in powerball_ranked],
|
||||
'recent_104_top_five': recent_104_top_five,
|
||||
'recent_104_powerball': recent_104_powerball,
|
||||
'weighted_top_five': weighted_top_five,
|
||||
'weighted_powerball': weighted_powerball,
|
||||
'aggressive_weighted_top_five': aggressive_weighted_top_five,
|
||||
'aggressive_weighted_powerball': aggressive_weighted_powerball
|
||||
}
|
||||
|
||||
|
||||
@@ -171,20 +272,80 @@ def generate_suggested_combination(stats: dict) -> None:
|
||||
print("Each draw is random and independent.\n")
|
||||
|
||||
top_five = stats['top_five_combined']
|
||||
top_ten = stats.get('top_ten_combined', [])
|
||||
powerball = stats['most_common_powerball']
|
||||
ranked_powerballs = stats.get('powerball_ranked', [])
|
||||
recent_104_top_five = stats.get('recent_104_top_five', [])
|
||||
recent_104_powerball = stats.get('recent_104_powerball')
|
||||
weighted_top_five = stats.get('weighted_top_five', [])
|
||||
weighted_powerball = stats.get('weighted_powerball')
|
||||
aggressive_weighted_top_five = stats.get('aggressive_weighted_top_five', [])
|
||||
aggressive_weighted_powerball = stats.get('aggressive_weighted_powerball')
|
||||
|
||||
if len(top_five) >= 5 and powerball:
|
||||
# Use the top 5 most frequent numbers from positions 1-5
|
||||
suggested_numbers = sorted(top_five[:5])
|
||||
primary_numbers = sorted(top_five[:5])
|
||||
primary_powerball = powerball
|
||||
|
||||
# Build a secondary set from the next-most-frequent historical numbers.
|
||||
secondary_pool = top_ten[5:10]
|
||||
if len(secondary_pool) < 5:
|
||||
secondary_pool = top_ten[:5]
|
||||
|
||||
secondary_numbers = sorted(secondary_pool[:5])
|
||||
secondary_powerball = ranked_powerballs[1] if len(ranked_powerballs) > 1 else primary_powerball
|
||||
|
||||
third_numbers = sorted(recent_104_top_five[:5]) if len(recent_104_top_five) >= 5 else []
|
||||
third_powerball = recent_104_powerball
|
||||
|
||||
fourth_numbers = sorted(weighted_top_five[:5]) if len(weighted_top_five) >= 5 else []
|
||||
fourth_powerball = weighted_powerball
|
||||
|
||||
fifth_numbers = sorted(aggressive_weighted_top_five[:5]) if len(aggressive_weighted_top_five) >= 5 else []
|
||||
fifth_powerball = aggressive_weighted_powerball
|
||||
|
||||
print(f"Suggested white ball numbers: {' '.join(map(str, suggested_numbers))}")
|
||||
print(f"Suggested Powerball number: {powerball}")
|
||||
print("Primary set (most frequent):")
|
||||
print(f" White balls: {' '.join(map(str, primary_numbers))}")
|
||||
print(f" Powerball: {primary_powerball}")
|
||||
|
||||
print("\nSecondary set (next-most frequent):")
|
||||
print(f" White balls: {' '.join(map(str, secondary_numbers))}")
|
||||
print(f" Powerball: {secondary_powerball}")
|
||||
|
||||
if third_numbers and third_powerball:
|
||||
print("\nThird set (most frequent in recent 104 draws):")
|
||||
print(f" White balls: {' '.join(map(str, third_numbers))}")
|
||||
print(f" Powerball: {third_powerball}")
|
||||
|
||||
if fourth_numbers and fourth_powerball:
|
||||
print("\nFourth set (weighted by recency):")
|
||||
print(f" White balls: {' '.join(map(str, fourth_numbers))}")
|
||||
print(f" Powerball: {fourth_powerball}")
|
||||
|
||||
if fifth_numbers and fifth_powerball:
|
||||
print("\nFifth set (aggressive recency weighting):")
|
||||
print(f" White balls: {' '.join(map(str, fifth_numbers))}")
|
||||
print(f" Powerball: {fifth_powerball}")
|
||||
print()
|
||||
print(f"Complete combination: {' '.join(map(str, suggested_numbers))} + {powerball}")
|
||||
print(f"Primary combination: {' '.join(map(str, primary_numbers))} + {primary_powerball}")
|
||||
print(f"Secondary combination: {' '.join(map(str, secondary_numbers))} + {secondary_powerball}")
|
||||
|
||||
if third_numbers and third_powerball:
|
||||
print(f"Third combination: {' '.join(map(str, third_numbers))} + {third_powerball}")
|
||||
|
||||
if fourth_numbers and fourth_powerball:
|
||||
print(f"Fourth combination: {' '.join(map(str, fourth_numbers))} + {fourth_powerball}")
|
||||
|
||||
if fifth_numbers and fifth_powerball:
|
||||
print(f"Fifth combination: {' '.join(map(str, fifth_numbers))} + {fifth_powerball}")
|
||||
print()
|
||||
print("This combination is based on:")
|
||||
print("These combinations are based on:")
|
||||
print(" • The 5 most frequently drawn numbers across all white ball positions")
|
||||
print(f" • The most frequently drawn Powerball number ({powerball})")
|
||||
print(f" • The most frequently drawn Powerball number ({primary_powerball})")
|
||||
print(" • A secondary set from the next-most-frequent white ball and Powerball values")
|
||||
print(" • Recent-window frequency (last 104 draws)")
|
||||
print(" • Recency-weighted scoring where newer draws count more")
|
||||
print(" • Aggressive recency weighting using a cubic curve")
|
||||
else:
|
||||
print("Insufficient data to generate a suggestion.")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user