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):
|
||||
"""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
@@ -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,
|
||||
)
|
||||
@@ -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
@@ -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
@@ -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
|
||||
Reference in new issue
Block a user