Reformat code to pythonic standards

This commit is contained in:
chris committed 2026-05-27 08:20:30 -04:00
1 parent ea62bdfc0b
commit b1732c07c5
5 files changed
+123 -51

No files matched your search

+3 -4
View File
@@ -1,6 +1,3 @@
import re
class InvalidStringException(Exception):
"""Raised when a string cannot be converted to an integer."""
pass
@@ -25,4 +22,6 @@ def convert_string_to_integer(data: str) -> int | Exception:
else:
return int(data)
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
View File
@@ -4,11 +4,12 @@
Utility functions for drawing data processing
"""
import os
from datetime import datetime, timedelta
from dotenv import load_dotenv
from data.database import PowerballDraw, MegaMillionsDraw, Table
from data.database import MegaMillionsDraw, PowerballDraw, Table
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
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
: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
Examples:
@@ -55,7 +60,7 @@ def get_next_draw_date(game: str | None, from_date: str | None = None) -> str |
"""
target_days = {
"powerball": [0, 2, 5],
"mega-millions": [1, 4]
"mega-millions": [1, 4],
}
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)
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
If the current date is a drawing date, the next previous date will be returned
Gets the previous drawing date from the current or specified date for the
given game
If the current date is a drawing date, the next previous date will be
returned
: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
Examples:
@@ -94,7 +104,7 @@ def get_previous_draw_date(game: str | None, from_date: str | None = None) -> st
"""
target_days = {
"powerball": [0, 2, 5],
"mega-millions": [1, 4]
"mega-millions": [1, 4],
}
return_date = None
@@ -110,7 +120,8 @@ def get_previous_draw_date(game: str | None, from_date: str | None = None) -> st
else:
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)
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
Examples:
>>> get_powerball_object(draw_date='2026-02-28', draw_result={'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)
>>> get_powerball_object(draw_date='2026-02-28', draw_result={
'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()
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
pb = draw_result['powerball']
power_play = draw_result['multiplier']
return PowerballDraw(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)
return PowerballDraw(
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_result: drawing results for the draw_date
:return: MegaMillionsDraw object
Examples:
>>> get_mega_millions_object(draw_date='2010-02-02', draw_result={'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)
>>> get_mega_millions_object(draw_date='2010-02-02', draw_result={
'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()
mb1, mb2, mb3, mb4, mb5 = draw_result['main_balls']
mega = draw_result['mega-ball']
megaplier = draw_result['multiplier']
return MegaMillionsDraw(draw_date=draw_date, main_ball1=mb1, main_ball2=mb2, main_ball3=mb3, main_ball4=mb4,
main_ball5=mb5, mega_ball=mega, megaplier=megaplier)
return MegaMillionsDraw(
draw_date=draw_date, main_ball1=mb1, main_ball2=mb2, main_ball3=mb3,
main_ball4=mb4,
main_ball5=mb5, mega_ball=mega, megaplier=megaplier,
)
+3
View File
@@ -4,10 +4,13 @@
Utility function for loading project environment variables
"""
import os
from dotenv import load_dotenv
load_dotenv()
def load_environment_variables() -> dict:
return {
k: v for k, v in os.environ.items()
+29 -12
View File
@@ -9,15 +9,18 @@ from math import comb
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 draw_count: The count of numbers to draw from the pool
:return: The total number of possible combinations
Example:
If a lottery game has a main ball pool of 49 numbers from which 5 numbers are drawn and a pool of
18 numbers from which 1 number is drawn (game ball), calculate the odds of winning that game.
If a lottery game has a main ball pool of 49 numbers from which 5
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)
1906884
@@ -26,7 +29,10 @@ def calculate_odds(pool_size: int, draw_count: int) -> int:
"""
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)
return total_combinations
@@ -35,29 +41,40 @@ def get_odds_of_winning(
main_ball_draw_pool: int,
main_ball_draw_count: int,
game_ball_draw_pool: int,
game_ball_draw_count: int
game_ball_draw_count: int,
) -> str:
"""
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_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_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
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.
>>> 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'
"""
if (main_ball_draw_count < 0 or main_ball_draw_count > 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.')
if (
main_ball_draw_count < 0 or main_ball_draw_count >
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)
game_ball_odds = calculate_odds(game_ball_draw_pool, game_ball_draw_count)
+43 -14
View File
@@ -4,19 +4,23 @@
Utility functions for scraping web data relative to selected games
"""
import httpx
from dateutil import parser, utils
from bs4 import BeautifulSoup
from dateutil import parser, utils
from util.environment import load_environment_variables
project_variables: dict = load_environment_variables()
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.
: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()
@@ -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}"
page = httpx.get(url)
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:
pick5 = []
draw_date = parser.parse(result.find(project_variables['LP_DRAW_DATE_CONTAINER'],
class_=project_variables['LP_DRAW_DATE_CLASS']).text).date().strftime('%Y-%m-%d')
main_balls = result.find_all(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']])
draw_date = parser.parse(
result.find(
project_variables['LP_DRAW_DATE_CONTAINER'],
class_=project_variables['LP_DRAW_DATE_CLASS'],
).text,
).date().strftime('%Y-%m-%d')
main_balls = result.find_all(
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:
pick5.append(int(ball.text.strip()))
@@ -55,8 +78,14 @@ def scrape_game_history(game: str, year: int = utils.today().year) -> dict:
multiplier = 1
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':
drawings[draw_date] = {'main_balls': pick5, 'powerball': game_ball, 'multiplier': multiplier}
drawings[draw_date] = {
'main_balls': pick5, 'powerball': game_ball,
'multiplier': multiplier,
}
return drawings