from datetime import datetime from collections import Counter import numpy as np import pandas as pd from sklearn.ensemble import RandomForestClassifier from sqlalchemy import select from data.database import Base, dal, project_variables import util.drawing as drawutil RANDOM_SEED = 42 def load_dataframe( table_name: str, start_date: datetime | None = None, end_date: datetime | None = None ) -> pd.DataFrame: """ :param table_name: the name of the table to load data from :param start_date: the start date for the data :param end_date: the end date for the data :returns: a pandas DataFrame containing the data """ dal.connect() session = dal.Session() game_dict = drawutil.check_table_name(table_name=table_name) if game_dict: target_table = Base.metadata.tables.get(game_dict['db_table_name']) if start_date is not None and end_date is not None: sql_statement = (select(target_table) .where(target_table.columns.draw_date >= start_date) .where(target_table.columns.draw_date <= end_date)) elif start_date is not None and end_date is None: sql_statement = (select(target_table).where(target_table.columns.draw_date >= start_date)) elif start_date is None and end_date is not None: sql_statement = (select(target_table).where(target_table.columns.draw_date <= end_date)) else: sql_statement = select(target_table) return pd.read_sql(sql_statement, session.bind) else: raise ValueError('An invalid table name was provided') def get_most_common_number( data_frame: pd.DataFrame, columns: list | None = None, top: int = 1 ) -> list[int]: """ :param data_frame: a pandas DataFrame containing the data :param columns: a list of column names to use :param top: the number of top (most seen) numbers to return :returns: a list of the most common numbers """ if columns is None: columns = ['main_ball1', 'main_ball2', 'main_ball3', 'main_ball4', 'main_ball5'] flat_numbers = data_frame[columns].values.flatten() counts = Counter(flat_numbers) return [int(num) for num, _ in counts.most_common(top)] def get_least_common_number( data_frame: pd.DataFrame, columns: list | None = None, bottom: int = 1 ) -> list[int]: """ :param data_frame: a pandas DataFrame containing the data :param columns: a list of column names to use :param bottom: the number of bottom (least seen) numbers to return :returns: a list of the least common numbers """ if columns is None: columns = ['main_ball1', 'main_ball2', 'main_ball3', 'main_ball4', 'main_ball5'] flat_numbers = data_frame[columns].values.flatten() counts = Counter(flat_numbers) return list(reversed([int(num) for num, _ in counts.most_common()[-bottom:]])) def calculate_probabilities( data_frame: pd.DataFrame, max_number: int, columns: list | None = None ) -> dict[int, float]: """ :param data_frame: A pandas DataFrame containing the data to calculate probabilities for :param max_number: The maximum number possible in the data_frame :param columns: The list of column names to use from the data_frame :returns dict: A dictionary containing the probabilities """ if columns is None: columns = ['main_ball1', 'main_ball2', 'main_ball3', 'main_ball4', 'main_ball5'] if data_frame.empty: return dict() # get all the numbers in the groups all_numbers = [num for group in data_frame[columns].values for num in group] # count all the occurrences of each number counts = Counter(all_numbers) # calculate the basic probability of each number occurring again probabilities = {num: counts.get(num, 0) / (max_number + 1) for num in range(1, max_number + 1)} # if any calculation is greater than one, use what is to the right of the decimal point as the value for key, value in probabilities.items(): if value > 1: probabilities[key] = value - int(str(value).split('.')[0]) # return the probability dict return probabilities def get_hot_numbers(probabilities: dict[int, float], top: int = 5) -> list[tuple[int, float]]: """ :param probabilities: A dictionary containing the probabilities :param top: The count of hottest items to return, defaults to 5 :returns list of tuples: A list of the hot numbers and their raw score """ return sorted(probabilities.items(), key=lambda item: item[1], reverse=True)[:top] def get_cold_numbers(probabilities: dict[int, float], bottom: int = 5) -> list[tuple[int, float]]: """ :param probabilities: A dictionary containing the probabilities :param bottom: The count of coldest items to return, defaults to 5 :returns list of tuples: A list of the hot numbers and their raw score """ return sorted(probabilities.items(), key=lambda item: item[1])[:bottom]