- Add check_cards_and_upload.py: Fetches card images from API and uploads to AWS S3
- Uses persistent aiohttp session for efficient connection reuse
- Supports cache-busting query parameters (?d=date) for Discord compatibility
- S3 URL structure: cards/cardset-{id:03d}/player-{id}/{type}card.png
- Configurable upload and player URL update flags
- Add analyze_cardset_rarity.py: Analyzes players by franchise and rarity
- Groups batters, pitchers, and combined totals
- Displays counts for all rarity tiers by franchise
- Provides comprehensive breakdown of cardset composition
- Add rank_pitching_staffs.py: Ranks teams 1-30 by pitching staff quality
- Point system based on rarity tiers (HoF=5, MVP=4, AS=3, etc.)
- Shows detailed rosters for top 5 and bottom 5 teams
- Useful for balance analysis and cardset evaluation
- Update CLAUDE.md with new scripts documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
182 lines
5.4 KiB
Python
182 lines
5.4 KiB
Python
import asyncio
|
|
from collections import defaultdict
|
|
from db_calls import db_get
|
|
|
|
|
|
async def analyze_cardset_rarity(cardset_id: int = 27):
|
|
"""Analyze players by franchise and rarity for a given cardset."""
|
|
|
|
print(f'Fetching players from cardset {cardset_id}...\n')
|
|
|
|
# Fetch all players from the cardset
|
|
p_query = await db_get(
|
|
'players',
|
|
params=[('cardset_id', cardset_id), ('inc_dex', False)]
|
|
)
|
|
|
|
if not p_query or p_query['count'] == 0:
|
|
print(f'No players found for cardset {cardset_id}')
|
|
return
|
|
|
|
players = p_query['players']
|
|
print(f'Found {len(players)} players\n')
|
|
|
|
# First pass: collect all unique rarity names
|
|
all_rarities = set()
|
|
for player in players:
|
|
rarity_obj = player.get('rarity', {})
|
|
if isinstance(rarity_obj, dict):
|
|
rarity_name = rarity_obj.get('name')
|
|
if rarity_name:
|
|
all_rarities.add(rarity_name)
|
|
|
|
sorted_rarities = sorted(all_rarities, key=lambda x: (
|
|
{'Common': 0, 'Uncommon': 1, 'Rare': 2, 'Epic': 3, 'Legend': 4,
|
|
'Starter': 0, 'Bench': 1, 'All-Star': 2, 'MVP': 3, 'Hall of Fame': 4}.get(x, 99), x
|
|
))
|
|
|
|
print(f'Found rarities: {sorted_rarities}\n')
|
|
|
|
# Group players by franchise and rarity
|
|
franchise_data = defaultdict(lambda: {
|
|
'batters': defaultdict(int),
|
|
'pitchers': defaultdict(int),
|
|
'combined': defaultdict(int)
|
|
})
|
|
|
|
for player in players:
|
|
franchise = player.get('franchise', 'Unknown')
|
|
rarity_obj = player.get('rarity', {})
|
|
|
|
# Extract rarity name from rarity object
|
|
if isinstance(rarity_obj, dict):
|
|
rarity = rarity_obj.get('name', 'Unknown')
|
|
else:
|
|
rarity = str(rarity_obj) if rarity_obj else 'Unknown'
|
|
|
|
# Determine if batter or pitcher based on positions
|
|
positions = []
|
|
for i in range(1, 9):
|
|
pos = player.get(f'pos_{i}')
|
|
if pos:
|
|
positions.append(pos)
|
|
|
|
is_pitcher = any(pos in ['SP', 'RP', 'CP'] for pos in positions)
|
|
|
|
if is_pitcher:
|
|
franchise_data[franchise]['pitchers'][rarity] += 1
|
|
else:
|
|
franchise_data[franchise]['batters'][rarity] += 1
|
|
|
|
franchise_data[franchise]['combined'][rarity] += 1
|
|
|
|
# Sort franchises alphabetically
|
|
sorted_franchises = sorted(franchise_data.keys())
|
|
|
|
# Print batters
|
|
print('=' * 100)
|
|
print('BATTERS BY FRANCHISE AND RARITY')
|
|
print('=' * 100)
|
|
|
|
# Build header dynamically
|
|
header = f'{"Franchise":<20}'
|
|
for rarity in sorted_rarities:
|
|
header += f' {rarity:<12}'
|
|
header += f' {"Total":<10}'
|
|
print(header)
|
|
print('-' * 100)
|
|
|
|
batter_totals = defaultdict(int)
|
|
for franchise in sorted_franchises:
|
|
batters = franchise_data[franchise]['batters']
|
|
total = sum(batters.values())
|
|
|
|
if total > 0:
|
|
row = f'{franchise:<20}'
|
|
for rarity in sorted_rarities:
|
|
count = batters.get(rarity, 0)
|
|
row += f' {count:<12}'
|
|
batter_totals[rarity] += count
|
|
row += f' {total:<10}'
|
|
batter_totals['Total'] += total
|
|
print(row)
|
|
|
|
print('-' * 100)
|
|
total_row = f'{"TOTAL":<20}'
|
|
for rarity in sorted_rarities:
|
|
total_row += f' {batter_totals[rarity]:<12}'
|
|
total_row += f' {batter_totals["Total"]:<10}'
|
|
print(total_row)
|
|
|
|
# Print pitchers
|
|
print('\n' + '=' * 100)
|
|
print('PITCHERS BY FRANCHISE AND RARITY')
|
|
print('=' * 100)
|
|
|
|
header = f'{"Franchise":<20}'
|
|
for rarity in sorted_rarities:
|
|
header += f' {rarity:<12}'
|
|
header += f' {"Total":<10}'
|
|
print(header)
|
|
print('-' * 100)
|
|
|
|
pitcher_totals = defaultdict(int)
|
|
for franchise in sorted_franchises:
|
|
pitchers = franchise_data[franchise]['pitchers']
|
|
total = sum(pitchers.values())
|
|
|
|
if total > 0:
|
|
row = f'{franchise:<20}'
|
|
for rarity in sorted_rarities:
|
|
count = pitchers.get(rarity, 0)
|
|
row += f' {count:<12}'
|
|
pitcher_totals[rarity] += count
|
|
row += f' {total:<10}'
|
|
pitcher_totals['Total'] += total
|
|
print(row)
|
|
|
|
print('-' * 100)
|
|
total_row = f'{"TOTAL":<20}'
|
|
for rarity in sorted_rarities:
|
|
total_row += f' {pitcher_totals[rarity]:<12}'
|
|
total_row += f' {pitcher_totals["Total"]:<10}'
|
|
print(total_row)
|
|
|
|
# Print combined
|
|
print('\n' + '=' * 100)
|
|
print('COMBINED (BATTERS + PITCHERS) BY FRANCHISE AND RARITY')
|
|
print('=' * 100)
|
|
|
|
header = f'{"Franchise":<20}'
|
|
for rarity in sorted_rarities:
|
|
header += f' {rarity:<12}'
|
|
header += f' {"Total":<10}'
|
|
print(header)
|
|
print('-' * 100)
|
|
|
|
combined_totals = defaultdict(int)
|
|
for franchise in sorted_franchises:
|
|
combined = franchise_data[franchise]['combined']
|
|
total = sum(combined.values())
|
|
|
|
row = f'{franchise:<20}'
|
|
for rarity in sorted_rarities:
|
|
count = combined.get(rarity, 0)
|
|
row += f' {count:<12}'
|
|
combined_totals[rarity] += count
|
|
row += f' {total:<10}'
|
|
combined_totals['Total'] += total
|
|
print(row)
|
|
|
|
print('-' * 100)
|
|
total_row = f'{"TOTAL":<20}'
|
|
for rarity in sorted_rarities:
|
|
total_row += f' {combined_totals[rarity]:<12}'
|
|
total_row += f' {combined_totals["Total"]:<10}'
|
|
print(total_row)
|
|
print('=' * 100)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
asyncio.run(analyze_cardset_rarity(27))
|