Reformat code to pythonic standards
This commit is contained in:
1 parent
ea62bdfc0b
commit
b1732c07c5
5 files changed
+123
-51
No files matched your search
+3
-4
@@ -1,6 +1,3 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class InvalidStringException(Exception):
|
class InvalidStringException(Exception):
|
||||||
"""Raised when a string cannot be converted to an integer."""
|
"""Raised when a string cannot be converted to an integer."""
|
||||||
pass
|
pass
|
||||||
@@ -25,4 +22,6 @@ def convert_string_to_integer(data: str) -> int | Exception:
|
|||||||
else:
|
else:
|
||||||
return int(data)
|
return int(data)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise InvalidStringException("The string could not be converted to an integer.") from exc
|
raise InvalidStringException(
|
||||||
|
"The string could not be converted to an integer.",
|
||||||
|
) from exc
|
||||||
+45
-21
@@ -4,11 +4,12 @@
|
|||||||
Utility functions for drawing data processing
|
Utility functions for drawing data processing
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from data.database import PowerballDraw, MegaMillionsDraw, Table
|
from data.database import MegaMillionsDraw, PowerballDraw, Table
|
||||||
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
@@ -38,13 +39,17 @@ def check_table_name2(table_name: Table) -> dict | None:
|
|||||||
return game_dict[table_name] if table_name in game_dict.keys() else None
|
return game_dict[table_name] if table_name in game_dict.keys() else None
|
||||||
|
|
||||||
|
|
||||||
def get_next_draw_date(game: str | None, from_date: str | None = None) -> str | None:
|
def get_next_draw_date(
|
||||||
|
game: str | None, from_date: str | None = None,
|
||||||
|
) -> str | None:
|
||||||
"""
|
"""
|
||||||
Gets the next drawing date from the current or specified date for the given game
|
Gets the next drawing date from the current or specified date for the
|
||||||
|
given game
|
||||||
If the current date is the next drawing date, the current date is returned
|
If the current date is the next drawing date, the current date is returned
|
||||||
|
|
||||||
:param game: megamillions or powerball
|
:param game: megamillions or powerball
|
||||||
:param from_date: date to get next drawing date from, if omitted the current date is used
|
:param from_date: date to get next drawing date from, if omitted the
|
||||||
|
current date is used
|
||||||
:return: next drawing date
|
:return: next drawing date
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@@ -55,7 +60,7 @@ def get_next_draw_date(game: str | None, from_date: str | None = None) -> str |
|
|||||||
"""
|
"""
|
||||||
target_days = {
|
target_days = {
|
||||||
"powerball": [0, 2, 5],
|
"powerball": [0, 2, 5],
|
||||||
"mega-millions": [1, 4]
|
"mega-millions": [1, 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
return_date = None
|
return_date = None
|
||||||
@@ -77,13 +82,18 @@ def get_next_draw_date(game: str | None, from_date: str | None = None) -> str |
|
|||||||
return return_date.strftime(return_date_format)
|
return return_date.strftime(return_date_format)
|
||||||
|
|
||||||
|
|
||||||
def get_previous_draw_date(game: str | None, from_date: str | None = None) -> str | None:
|
def get_previous_draw_date(
|
||||||
|
game: str | None, from_date: str | None = None,
|
||||||
|
) -> str | None:
|
||||||
"""
|
"""
|
||||||
Gets the previous drawing date from the current or specified date for the given game
|
Gets the previous drawing date from the current or specified date for the
|
||||||
If the current date is a drawing date, the next previous date will be returned
|
given game
|
||||||
|
If the current date is a drawing date, the next previous date will be
|
||||||
|
returned
|
||||||
|
|
||||||
:param game: megamillions or powerball
|
:param game: megamillions or powerball
|
||||||
:param from_date: date to get previous drawing date from, if omitted the current date is used
|
:param from_date: date to get previous drawing date from, if omitted the
|
||||||
|
current date is used
|
||||||
:return: previous drawing date
|
:return: previous drawing date
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@@ -94,7 +104,7 @@ def get_previous_draw_date(game: str | None, from_date: str | None = None) -> st
|
|||||||
"""
|
"""
|
||||||
target_days = {
|
target_days = {
|
||||||
"powerball": [0, 2, 5],
|
"powerball": [0, 2, 5],
|
||||||
"mega-millions": [1, 4]
|
"mega-millions": [1, 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
return_date = None
|
return_date = None
|
||||||
@@ -110,7 +120,8 @@ def get_previous_draw_date(game: str | None, from_date: str | None = None) -> st
|
|||||||
else:
|
else:
|
||||||
return_date = datetime.strptime(from_date, return_date_format)
|
return_date = datetime.strptime(from_date, return_date_format)
|
||||||
|
|
||||||
# to ensure the current date is not returned if it is a draw date, subtract a day first
|
# to ensure the current date is not returned if it is a draw date,
|
||||||
|
# subtract a day first
|
||||||
return_date -= timedelta(days=1)
|
return_date -= timedelta(days=1)
|
||||||
|
|
||||||
while return_date.weekday() not in target_days[game]:
|
while return_date.weekday() not in target_days[game]:
|
||||||
@@ -126,32 +137,45 @@ def get_powerball_object(draw_date: str, draw_result: dict) -> PowerballDraw:
|
|||||||
:return: PowerballDraw object
|
:return: PowerballDraw object
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> get_powerball_object(draw_date='2026-02-28', draw_result={'main_balls': [6, 20, 35, 54, 65], 'powerball': 10, 'multiplier': 4})
|
>>> get_powerball_object(draw_date='2026-02-28', draw_result={
|
||||||
PowerballDraw(draw_date=datetime(2026, 2, 28), main_ball1=6, main_ball2=20, main_ball3=35, main_ball4=54, main_ball5=65, powerball=10, power_play=4)
|
'main_balls': [6, 20, 35, 54, 65], 'powerball': 10, 'multiplier': 4})
|
||||||
|
PowerballDraw(draw_date=datetime(2026, 2, 28), main_ball1=6,
|
||||||
|
main_ball2=20, main_ball3=35, main_ball4=54, main_ball5=65, powerball=10,
|
||||||
|
power_play=4)
|
||||||
"""
|
"""
|
||||||
draw_date = datetime.strptime(draw_date, '%Y-%m-%d').date()
|
draw_date = datetime.strptime(draw_date, '%Y-%m-%d').date()
|
||||||
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
|
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
|
||||||
pb = draw_result['powerball']
|
pb = draw_result['powerball']
|
||||||
power_play = draw_result['multiplier']
|
power_play = draw_result['multiplier']
|
||||||
|
|
||||||
return PowerballDraw(draw_date=draw_date,main_ball1=mb1, main_ball2=mb2, main_ball3=mb3, main_ball4=mb4,
|
return PowerballDraw(
|
||||||
main_ball5=mb5, powerball=pb, power_play=power_play)
|
draw_date=draw_date, main_ball1=mb1, main_ball2=mb2, main_ball3=mb3,
|
||||||
|
main_ball4=mb4,
|
||||||
|
main_ball5=mb5, powerball=pb, power_play=power_play,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_mega_millions_object(draw_date: str, draw_result: dict) -> MegaMillionsDraw:
|
def get_mega_millions_object(
|
||||||
|
draw_date: str, draw_result: dict,
|
||||||
|
) -> MegaMillionsDraw:
|
||||||
"""
|
"""
|
||||||
:param draw_date: date for the drawing data
|
:param draw_date: date for the drawing data
|
||||||
:param draw_result: drawing results for the draw_date
|
:param draw_result: drawing results for the draw_date
|
||||||
:return: MegaMillionsDraw object
|
:return: MegaMillionsDraw object
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> get_mega_millions_object(draw_date='2010-02-02', draw_result={'main_balls': [6, 7, 26, 27, 49], 'mega-ball': 9, 'megaplier': 4})
|
>>> get_mega_millions_object(draw_date='2010-02-02', draw_result={
|
||||||
MegaMillionsDraw(draw_date=date, main_ball1=6, main_ball2=7, main_ball3=26, main_ball4=27, main_ball5=49, mega_ball=9, megaplier=4)
|
'main_balls': [6, 7, 26, 27, 49], 'mega-ball': 9, 'megaplier': 4})
|
||||||
|
MegaMillionsDraw(draw_date=date, main_ball1=6, main_ball2=7,
|
||||||
|
main_ball3=26, main_ball4=27, main_ball5=49, mega_ball=9, megaplier=4)
|
||||||
"""
|
"""
|
||||||
draw_date = datetime.strptime(draw_date, '%Y-%m-%d').date()
|
draw_date = datetime.strptime(draw_date, '%Y-%m-%d').date()
|
||||||
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
|
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
|
||||||
mega = draw_result['mega-ball']
|
mega = draw_result['mega-ball']
|
||||||
megaplier = draw_result['multiplier']
|
megaplier = draw_result['multiplier']
|
||||||
|
|
||||||
return MegaMillionsDraw(draw_date=draw_date, main_ball1=mb1, main_ball2=mb2, main_ball3=mb3, main_ball4=mb4,
|
return MegaMillionsDraw(
|
||||||
main_ball5=mb5, mega_ball=mega, megaplier=megaplier)
|
draw_date=draw_date, main_ball1=mb1, main_ball2=mb2, main_ball3=mb3,
|
||||||
|
main_ball4=mb4,
|
||||||
|
main_ball5=mb5, mega_ball=mega, megaplier=megaplier,
|
||||||
|
)
|
||||||
@@ -4,10 +4,13 @@
|
|||||||
Utility function for loading project environment variables
|
Utility function for loading project environment variables
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
|
||||||
def load_environment_variables() -> dict:
|
def load_environment_variables() -> dict:
|
||||||
return {
|
return {
|
||||||
k: v for k, v in os.environ.items()
|
k: v for k, v in os.environ.items()
|
||||||
|
|||||||
+29
-12
@@ -9,15 +9,18 @@ from math import comb
|
|||||||
|
|
||||||
def calculate_odds(pool_size: int, draw_count: int) -> int:
|
def calculate_odds(pool_size: int, draw_count: int) -> int:
|
||||||
"""
|
"""
|
||||||
Calculate the total number of possible combinations in a set of numbers with a specific draw count.
|
Calculate the total number of possible combinations in a set of numbers
|
||||||
|
with a specific draw count.
|
||||||
|
|
||||||
:param pool_size: Total count of numbers in the pool
|
:param pool_size: Total count of numbers in the pool
|
||||||
:param draw_count: The count of numbers to draw from the pool
|
:param draw_count: The count of numbers to draw from the pool
|
||||||
:return: The total number of possible combinations
|
:return: The total number of possible combinations
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
If a lottery game has a main ball pool of 49 numbers from which 5 numbers are drawn and a pool of
|
If a lottery game has a main ball pool of 49 numbers from which 5
|
||||||
18 numbers from which 1 number is drawn (game ball), calculate the odds of winning that game.
|
numbers are drawn and a pool of
|
||||||
|
18 numbers from which 1 number is drawn (game ball), calculate the
|
||||||
|
odds of winning that game.
|
||||||
|
|
||||||
>>> calculate_odds(pool_size=49, draw_count=5)
|
>>> calculate_odds(pool_size=49, draw_count=5)
|
||||||
1906884
|
1906884
|
||||||
@@ -26,7 +29,10 @@ def calculate_odds(pool_size: int, draw_count: int) -> int:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if draw_count < 0 or draw_count > pool_size:
|
if draw_count < 0 or draw_count > pool_size:
|
||||||
raise ValueError('Integer values must be positive and draw counts must be less than pool size.')
|
raise ValueError(
|
||||||
|
'Integer values must be positive and draw counts must be less '
|
||||||
|
'than pool size.',
|
||||||
|
)
|
||||||
total_combinations = comb(pool_size, draw_count)
|
total_combinations = comb(pool_size, draw_count)
|
||||||
return total_combinations
|
return total_combinations
|
||||||
|
|
||||||
@@ -35,29 +41,40 @@ def get_odds_of_winning(
|
|||||||
main_ball_draw_pool: int,
|
main_ball_draw_pool: int,
|
||||||
main_ball_draw_count: int,
|
main_ball_draw_count: int,
|
||||||
game_ball_draw_pool: int,
|
game_ball_draw_pool: int,
|
||||||
game_ball_draw_count: int
|
game_ball_draw_count: int,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Calculate the odds of winning a specific lottery game with one draw
|
Calculate the odds of winning a specific lottery game with one draw
|
||||||
|
|
||||||
:param main_ball_draw_pool: Total count of numbers in the main ball pool
|
:param main_ball_draw_pool: Total count of numbers in the main ball pool
|
||||||
:param main_ball_draw_count: The count of numbers to draw from the main ball pool
|
:param main_ball_draw_count: The count of numbers to draw from the
|
||||||
|
main ball pool
|
||||||
:param game_ball_draw_pool: Total count of numbers in the game ball pool
|
:param game_ball_draw_pool: Total count of numbers in the game ball pool
|
||||||
:param game_ball_draw_count: The count of numbers to draw from the game ball pool
|
:param game_ball_draw_count: The count of numbers to draw from the
|
||||||
|
game ball pool
|
||||||
|
|
||||||
:return: The odds of winning a specific lottery game with one draw
|
:return: The odds of winning a specific lottery game with one draw
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
To calculate the odds of winning a lottery game with 5 numbers drawn from a main ball pool of 49 and
|
To calculate the odds of winning a lottery game with 5 numbers
|
||||||
|
drawn from a main ball pool of 49 and
|
||||||
1 number drawn from a game ball pool of 19 numbers.
|
1 number drawn from a game ball pool of 19 numbers.
|
||||||
|
|
||||||
>>> get_odds_of_winning(main_ball_draw_pool=49, main_ball_draw_count=5, game_ball_draw_pool=18, game_ball_draw_count=1)
|
>>> get_odds_of_winning(main_ball_draw_pool=49,
|
||||||
|
main_ball_draw_count=5, game_ball_draw_pool=18,
|
||||||
|
game_ball_draw_count=1)
|
||||||
'The odds of winning are 1 in 34,323,912'
|
'The odds of winning are 1 in 34,323,912'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (main_ball_draw_count < 0 or main_ball_draw_count > main_ball_draw_pool or
|
if (
|
||||||
game_ball_draw_count < 0 or game_ball_draw_count > game_ball_draw_pool):
|
main_ball_draw_count < 0 or main_ball_draw_count >
|
||||||
raise ValueError('Integer values must be positive and draw counts must be less than pool size.')
|
main_ball_draw_pool or
|
||||||
|
game_ball_draw_count < 0 or game_ball_draw_count >
|
||||||
|
game_ball_draw_pool):
|
||||||
|
raise ValueError(
|
||||||
|
'Integer values must be positive and draw counts must be less '
|
||||||
|
'than pool size.',
|
||||||
|
)
|
||||||
|
|
||||||
main_ball_odds = calculate_odds(main_ball_draw_pool, main_ball_draw_count)
|
main_ball_odds = calculate_odds(main_ball_draw_pool, main_ball_draw_count)
|
||||||
game_ball_odds = calculate_odds(game_ball_draw_pool, game_ball_draw_count)
|
game_ball_odds = calculate_odds(game_ball_draw_pool, game_ball_draw_count)
|
||||||
|
|||||||
+43
-14
@@ -4,19 +4,23 @@
|
|||||||
Utility functions for scraping web data relative to selected games
|
Utility functions for scraping web data relative to selected games
|
||||||
"""
|
"""
|
||||||
import httpx
|
import httpx
|
||||||
from dateutil import parser, utils
|
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
from dateutil import parser, utils
|
||||||
|
|
||||||
from util.environment import load_environment_variables
|
from util.environment import load_environment_variables
|
||||||
|
|
||||||
|
|
||||||
project_variables: dict = load_environment_variables()
|
project_variables: dict = load_environment_variables()
|
||||||
|
|
||||||
|
|
||||||
def scrape_game_history(game: str, year: int = utils.today().year) -> dict:
|
def scrape_game_history(game: str, year: int = utils.today().year) -> dict:
|
||||||
"""
|
"""
|
||||||
Scrape game data from the url provided. This function requires specific environment variables be present
|
Scrape game data from the url provided. This function requires
|
||||||
|
specific environment variables be present
|
||||||
in order to function properly.
|
in order to function properly.
|
||||||
:param:game The target game to scrape.
|
:param:game The target game to scrape.
|
||||||
:param:year The year to scrape. If no year is provided, scrapes games from the current year.
|
:param:year The year to scrape. If no year is provided, scrapes
|
||||||
|
games from the current year.
|
||||||
|
|
||||||
:return: dict()
|
:return: dict()
|
||||||
|
|
||||||
@@ -32,18 +36,37 @@ def scrape_game_history(game: str, year: int = utils.today().year) -> dict:
|
|||||||
url = f"{project_variables['LP_BASE_SCRAPE_URL']}{game}/numbers/{year}"
|
url = f"{project_variables['LP_BASE_SCRAPE_URL']}{game}/numbers/{year}"
|
||||||
page = httpx.get(url)
|
page = httpx.get(url)
|
||||||
soup = BeautifulSoup(page.text, 'html.parser')
|
soup = BeautifulSoup(page.text, 'html.parser')
|
||||||
results = soup.find_all(project_variables['LP_RESULT_CONTAINER'], class_=project_variables['LP_RESULT_CLASS'])
|
results = soup.find_all(
|
||||||
|
project_variables['LP_RESULT_CONTAINER'],
|
||||||
|
class_=project_variables['LP_RESULT_CLASS'],
|
||||||
|
)
|
||||||
|
|
||||||
for result in results:
|
for result in results:
|
||||||
pick5 = []
|
pick5 = []
|
||||||
draw_date = parser.parse(result.find(project_variables['LP_DRAW_DATE_CONTAINER'],
|
draw_date = parser.parse(
|
||||||
class_=project_variables['LP_DRAW_DATE_CLASS']).text).date().strftime('%Y-%m-%d')
|
result.find(
|
||||||
main_balls = result.find_all(project_variables['LP_BALL_CONTAINER'], class_=project_variables['LP_BALL_CLASS'])
|
project_variables['LP_DRAW_DATE_CONTAINER'],
|
||||||
game_ball = result.find(project_variables['LP_BALL_CONTAINER'],
|
class_=project_variables['LP_DRAW_DATE_CLASS'],
|
||||||
class_=[project_variables['LP_POWERBALL_CLASS'], project_variables['LP_MEGABALL_CLASS']])
|
).text,
|
||||||
multiplier = result.find(project_variables['LP_BALL_CONTAINER'],
|
).date().strftime('%Y-%m-%d')
|
||||||
class_=[project_variables['LP_POWERBALL_MULTIPLIER_CLASS'],
|
main_balls = result.find_all(
|
||||||
project_variables['LP_MEGA_MILLIONS_MULTIPLIER_CLASS']])
|
project_variables['LP_BALL_CONTAINER'],
|
||||||
|
class_=project_variables['LP_BALL_CLASS'],
|
||||||
|
)
|
||||||
|
game_ball = result.find(
|
||||||
|
project_variables['LP_BALL_CONTAINER'],
|
||||||
|
class_=[
|
||||||
|
project_variables['LP_POWERBALL_CLASS'],
|
||||||
|
project_variables['LP_MEGABALL_CLASS'],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
multiplier = result.find(
|
||||||
|
project_variables['LP_BALL_CONTAINER'],
|
||||||
|
class_=[
|
||||||
|
project_variables['LP_POWERBALL_MULTIPLIER_CLASS'],
|
||||||
|
project_variables['LP_MEGA_MILLIONS_MULTIPLIER_CLASS'],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
for ball in main_balls:
|
for ball in main_balls:
|
||||||
pick5.append(int(ball.text.strip()))
|
pick5.append(int(ball.text.strip()))
|
||||||
@@ -55,8 +78,14 @@ def scrape_game_history(game: str, year: int = utils.today().year) -> dict:
|
|||||||
multiplier = 1
|
multiplier = 1
|
||||||
|
|
||||||
if game == 'mega-millions':
|
if game == 'mega-millions':
|
||||||
drawings[draw_date] = {'main_balls': pick5, 'mega-ball': game_ball, 'multiplier': multiplier}
|
drawings[draw_date] = {
|
||||||
|
'main_balls': pick5, 'mega-ball': game_ball,
|
||||||
|
'multiplier': multiplier,
|
||||||
|
}
|
||||||
elif game == 'powerball':
|
elif game == 'powerball':
|
||||||
drawings[draw_date] = {'main_balls': pick5, 'powerball': game_ball, 'multiplier': multiplier}
|
drawings[draw_date] = {
|
||||||
|
'main_balls': pick5, 'powerball': game_ball,
|
||||||
|
'multiplier': multiplier,
|
||||||
|
}
|
||||||
|
|
||||||
return drawings
|
return drawings
|
||||||
Reference in new issue
Block a user