Adjusted logging across the files

This commit is contained in:
matt 2025-01-17 18:04:29 -08:00
parent 1c7436f33d
commit 76277f876c
12 changed files with 228 additions and 160 deletions

9
.gitignore vendored
View file

@ -2,7 +2,12 @@
*.json
*.log
*.txt
!requirements.txt
test.py
.mypy_cache/
test.py
main.spec
!requirements.txt
__pycache__/
build/
csv_files/
dist/
logs/

View file

@ -29,6 +29,7 @@ Typical usage example:
# Standard library imports
import functools
import logging
import os
import time
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union, cast
@ -72,12 +73,35 @@ from settings import (
)
from type_definitions import CardLibraryDF, CommanderDF, LandDF
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# Create logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/builder_utils.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# Type variables for generic functions
T = TypeVar('T')
DataFrame = TypeVar('DataFrame', bound=pd.DataFrame)

View file

@ -1,44 +0,0 @@
from __future__ import annotations
import inquirer.prompt # type: ignore
import pandas as pd # type: ignore
import pprint
from fuzzywuzzy import fuzz, process # type: ignore
from IPython.display import display
pd.set_option('display.max_colwidth', None)
pd.set_option('display.expand_frame_repr', True)
pd.options.mode.chained_assignment = None
def get_card_info():
question = [
inquirer.Text(
'card_prompt',
message='Enter a card name:'
)
]
answer = inquirer.prompt(question)
card_choice = answer['card_prompt']
df = pd.read_csv('csv_files/cards.csv', low_memory=False)
fuzzy_card_choice = process.extractOne(card_choice, df['name'], scorer=fuzz.ratio)
fuzzy_card_choice = fuzzy_card_choice[0]
filtered_df = df[df['name'] == fuzzy_card_choice]
columns_to_keep = ['name', 'colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'keywords', 'power', 'toughness', 'text']
filtered_df = filtered_df[filtered_df['layout'].str.contains('reversible_card') == False]
filtered_df = filtered_df[filtered_df['availability'].str.contains('arena') == False]
filtered_df.drop_duplicates(subset='name', keep='first', inplace=True)
filtered_df = filtered_df[columns_to_keep].astype('string')
columns_to_keep = ['name', 'colorIdentity', 'colors', 'manaCost', 'manaValue', 'type', 'keywords', 'power', 'toughness']
filtered_df_no_text = filtered_df[columns_to_keep]
filtered_df_no_text.dropna(how='all', axis=1, inplace=True)
df_dict = filtered_df.to_dict('list')
pprint.pprint(df_dict, sort_dicts=False)
pprint.pprint(filtered_df_no_text)
pprint.pprint(filtered_df['text'])
#get_card_info()

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import logging
import math
import numpy as np
import os
import random
import time
from functools import lru_cache
@ -20,7 +21,7 @@ from settings import (
COMMANDER_CSV_PATH, FUZZY_MATCH_THRESHOLD, MAX_FUZZY_CHOICES, FETCH_LAND_DEFAULT_COUNT,
COMMANDER_POWER_DEFAULT, COMMANDER_TOUGHNESS_DEFAULT, COMMANDER_MANA_COST_DEFAULT,
COMMANDER_MANA_VALUE_DEFAULT, COMMANDER_TYPE_DEFAULT, COMMANDER_TEXT_DEFAULT,
THEME_PRIORITY_BONUS, THEME_POOL_SIZE_MULTIPLIER,
THEME_PRIORITY_BONUS, THEME_POOL_SIZE_MULTIPLIER, DECK_DIRECTORY,
COMMANDER_COLOR_IDENTITY_DEFAULT, COMMANDER_COLORS_DEFAULT, COMMANDER_TAGS_DEFAULT,
COMMANDER_THEMES_DEFAULT, COMMANDER_CREATURE_TYPES_DEFAULT, DUAL_LAND_TYPE_MAP,
CSV_READ_TIMEOUT, CSV_PROCESSING_BATCH_SIZE, CSV_VALIDATION_RULES, CSV_REQUIRED_COLUMNS,
@ -89,12 +90,34 @@ except ImportError:
logging.warning("Scrython is not installed. Price checking features will be unavailable."
)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# Create logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/deck_builder.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
@ -480,9 +503,7 @@ class DeckBuilder:
self.fill_out_deck()
# Process and organize deck
self.card_library.to_csv(f'{CSV_DIRECTORY}/test_deck_presort.csv', index=False)
self.organize_library()
self.card_library.to_csv(f'{CSV_DIRECTORY}/test_deck_preconcat.csv', index=False)
# Log deck composition
self._log_deck_composition()
@ -496,8 +517,9 @@ class DeckBuilder:
self.commander_to_top()
# Save final deck
self.card_library.to_csv(f'{CSV_DIRECTORY}/test_deck_done.csv', index=False)
self.full_df.to_csv(f'{CSV_DIRECTORY}/test_all_after_done.csv', index=False)
FILE_TIME = time.strftime("%Y%m%d-%H%M%S")
DECK_FILE = f'{self.commander}_{FILE_TIME}.csv'
self.card_library.to_csv(f'{DECK_DIRECTORY}/{DECK_FILE}', index=False)
except Exception as e:
raise DeckBuilderError(f"Failed to initialize deck building: {str(e)}")

View file

@ -3,6 +3,7 @@
from __future__ import annotations
import logging
import os
from typing import Any, List, Optional, Tuple, Union
import inquirer.prompt
@ -28,13 +29,35 @@ from exceptions import (
PriceValidationError
)
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# Create logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/input_handler.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
class InputHandler:
"""Handles user input operations with validation and error handling.

47
main.py
View file

@ -1,3 +1,10 @@
"""Command-line interface for the MTG Python Deckbuilder application.
This module provides the main menu and user interaction functionality for the
MTG Python Deckbuilder. It handles menu display, user input processing, and
routing to different application features like setup, deck building, card info
lookup and CSV file tagging.
"""
from __future__ import annotations
# Standard library imports
@ -15,26 +22,34 @@ import deck_builder
import setup
import tagger
"""Command-line interface for the MTG Python Deckbuilder application.
This module provides the main menu and user interaction functionality for the
MTG Python Deckbuilder. It handles menu display, user input processing, and
routing to different application features like setup, deck building, card info
lookup and CSV file tagging.
"""
# Create logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('logs/main.log', mode='a', encoding='utf-8')
]
)
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = os.path.join(LOG_DIR, 'main.log')
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# Menu constants
MENU_SETUP = 'Setup'
@ -93,6 +108,8 @@ def run_menu() -> NoReturn:
"""
logger.info("Starting MTG Python Deckbuilder")
Path('csv_files').mkdir(parents=True, exist_ok=True)
Path('deck_files').mkdir(parents=True, exist_ok=True)
Path('logs').mkdir(parents=True, exist_ok=True)
while True:
try:

View file

@ -1,44 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['C:\\Users\\Matt\\mtg_python\\mtg_python_deckbuilder\\main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main',
)

View file

@ -36,6 +36,31 @@ from settings import (
)
from type_definitions import PriceCache
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/price_check.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
class PriceChecker:
"""Class for handling MTG card price checking and validation.
@ -65,12 +90,6 @@ class PriceChecker:
self.max_deck_price: float = max_deck_price
self.current_deck_price: float = 0.0
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
@lru_cache(maxsize=PRICE_CACHE_SIZE)
def get_card_price(self, card_name: str, attempts: int = 0) -> float:
"""Get the price of a card with caching and retry logic.
@ -116,7 +135,7 @@ class PriceChecker:
except scrython.foundation.ScryfallError as e:
if attempts < MAX_PRICE_CHECK_ATTEMPTS:
logging.warning(f"Retrying price check for {card_name} (attempt {attempts + 1})")
logger.warning(f"Retrying price check for {card_name} (attempt {attempts + 1})")
return self.get_card_price(card_name, attempts + 1)
raise PriceAPIError(card_name, {"error": str(e)})
@ -125,7 +144,7 @@ class PriceChecker:
except Exception as e:
if attempts < MAX_PRICE_CHECK_ATTEMPTS:
logging.warning(f"Unexpected error checking price for {card_name}, retrying")
logger.warning(f"Unexpected error checking price for {card_name}, retrying")
return self.get_card_price(card_name, attempts + 1)
raise PriceAPIError(card_name, {"error": str(e)})
@ -184,10 +203,10 @@ class PriceChecker:
results[card_name] = price
except Exception as e:
errors.append((card_name, e))
logging.error(f"Error checking price for {card_name}: {e}")
logger.error(f"Error checking price for {card_name}: {e}")
if errors:
logging.warning(f"Failed to get prices for {len(errors)} cards")
logger.warning(f"Failed to get prices for {len(errors)} cards")
return results
@ -198,10 +217,10 @@ class PriceChecker:
price: Price to add to current deck total
"""
self.current_deck_price += price
logging.debug(f"Updated deck price to ${self.current_deck_price:.2f}")
logger.debug(f"Updated deck price to ${self.current_deck_price:.2f}")
def clear_cache(self) -> None:
"""Clear the price cache."""
self.price_cache.clear()
self.get_card_price.cache_clear()
logging.info("Price cache cleared")
logger.info("Price cache cleared")

View file

@ -788,6 +788,7 @@ TYPE_TAG_MAPPING = {
}
CSV_DIRECTORY = 'csv_files'
DECK_DIRECTORY = 'deck_files'
# Color identity constants and mappings

View file

@ -54,15 +54,30 @@ from exceptions import (
if not os.path.exists('logs'):
os.makedirs('logs')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('logs/setup.log', mode='w', encoding='utf-8')
]
)
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/setup.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
def check_csv_exists(file_path: Union[str, Path]) -> bool:
"""Check if a CSV file exists at the specified path.

View file

@ -53,15 +53,30 @@ from type_definitions import CardLibraryDF
if not os.path.exists('logs'):
os.makedirs('logs')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('logs/setup_utils.log', mode='a', encoding='utf-8')
]
)
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/setup_utils.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# Type definitions
class FilterRule(TypedDict):

View file

@ -44,15 +44,30 @@ PATTERN_GROUPS = {
if not os.path.exists('logs'):
os.makedirs('logs')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('logs/tagger.log', mode='w', encoding='utf-8')
]
)
# Logging configuration
LOG_DIR = 'logs'
LOG_FILE = f'{LOG_DIR}/tagger.log'
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
LOG_LEVEL = logging.INFO
# Create formatters and handlers
formatter = logging.Formatter(LOG_FORMAT)
# File handler
file_handler = logging.FileHandler(LOG_FILE, mode='w', encoding='utf-8')
file_handler.setFormatter(formatter)
# Stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
# Create logger for this module
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
# Add handlers to logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
### Setup
## Load the dataframe