Spaces:
Configuration error
Configuration error
Download generate_form_guides.py from Brettapps/Trifecta-Lab: direct link, hf CLI and curl.
- Browser
- Download file 11.4 kB
-
https://huggingface.co/spaces/Brettapps/Trifecta-Lab/resolve/main/generate_form_guides.py
- Command line
-
hf download hf://spaces/Brettapps/Trifecta-Lab/generate_form_guides.py
-
curl -L -o generate_form_guides.py https://huggingface.co/spaces/Brettapps/Trifecta-Lab/resolve/main/generate_form_guides.py
11.4 kB
| """Generate comprehensive form guide for all horses racing today.""" | |
| import json | |
| from pathlib import Path | |
| from collections import defaultdict | |
| from datetime import datetime | |
| DATA_DIR = Path('/home/brettanthonysjoberg179/trifecta-bro-hf-space/data') | |
| CACHE_DIR = DATA_DIR / 'cache' | |
| RESULTS_DIR = DATA_DIR / 'results' | |
| REPORTS_DIR = DATA_DIR / 'reports' | |
| VAULT_DIR = Path('/home/brettanthonysjoberg179/Documents/Obsidian Vault') | |
| DATABANK_DIR = VAULT_DIR / 'Horse Form Databank' | |
| FORM_GUIDES_DIR = DATABANK_DIR / 'Form-Guides' | |
| def ensure_dirs(): | |
| FORM_GUIDES_DIR.mkdir(parents=True, exist_ok=True) | |
| def load_all_cached_races(date: str) -> list[dict]: | |
| races = [] | |
| for f in CACHE_DIR.glob('*.json'): | |
| try: | |
| with open(f) as fp: | |
| data = json.load(fp) | |
| if data.get('date') == date and 'track' in data: | |
| races.append(data) | |
| except: | |
| continue | |
| return races | |
| def parse_num(s): | |
| return int(str(s).replace('e', '').replace('E', '')) | |
| def generate_horse_form_guide(horse: dict) -> str: | |
| """Generate comprehensive form guide for a single horse.""" | |
| name = horse.get('name', 'Unknown') | |
| number = horse.get('number', 0) | |
| barrier = horse.get('barrier', 0) | |
| weight = horse.get('weight', 0) | |
| age = horse.get('age', 0) | |
| sex = horse.get('sex', '') | |
| sire = horse.get('sire', '') | |
| dam = horse.get('dam', '') | |
| jockey = horse.get('jockey', '') | |
| trainer = horse.get('trainer', '') | |
| form = horse.get('form', '') | |
| last20 = horse.get('last20_starts', '') | |
| career_prize = horse.get('career_prize_money', '$0') | |
| stats = horse.get('stats', {}) | |
| overall = stats.get('overall', {}) | |
| track = stats.get('track', {}) | |
| distance = stats.get('distance', {}) | |
| track_dist = stats.get('trackDistance', {}) | |
| condition = stats.get('condition', {}) | |
| first_up = stats.get('firstUp', {}) | |
| second_up = stats.get('secondUp', {}) | |
| # Get all condition stats | |
| cond_stats = stats.get('conditions', {}) | |
| note = f"""# {name} | |
| ## Race Details | |
| - **Number**: {number} | |
| - **Barrier**: {barrier} | |
| - **Weight**: {weight}kg | |
| - **Jockey**: {jockey} | |
| - **Trainer**: {trainer} | |
| - **Age/Sex**: {age}yo {sex} | |
| - **Sire**: {sire} | |
| - **Dam**: {dam} | |
| - **Career Prize**: {career_prize} | |
| ## Career Statistics | |
| | Metric | Overall | Track | Distance | Track+Dist | Condition | | |
| |--------|---------|-------|----------|------------|-----------| | |
| | Starts | {overall.get('starts', 0)} | {track.get('starts', 0)} | {distance.get('starts', 0)} | {track_dist.get('starts', 0)} | {condition.get('starts', 0)} | | |
| | Wins | {overall.get('wins', 0)} | {track.get('wins', 0)} | {distance.get('wins', 0)} | {track_dist.get('wins', 0)} | {condition.get('wins', 0)} | | |
| | Places | {overall.get('places', 0)} | {track.get('places', 0)} | {distance.get('places', 0)} | {track_dist.get('places', 0)} | {condition.get('places', 0)} | | |
| | Win % | {overall.get('winPercent', 0)*100:.1f}% | {track.get('winPercent', 0)*100:.1f}% | {distance.get('winPercent', 0)*100:.1f}% | {track_dist.get('winPercent', 0)*100:.1f}% | {condition.get('winPercent', 0)*100:.1f}% | | |
| | Place % | {overall.get('placePercent', 0)*100:.1f}% | {track.get('placePercent', 0)*100:.1f}% | {distance.get('placePercent', 0)*100:.1f}% | {track_dist.get('placePercent', 0)*100:.1f}% | {condition.get('placePercent', 0)*100:.1f}% | | |
| ## Fitness Profile | |
| | First-Up | Second-Up | | |
| |----------|-----------| | |
| | {first_up.get('starts', 0)} starts, {first_up.get('wins', 0)} wins ({first_up.get('winPercent', 0)*100:.1f}%) | {second_up.get('starts', 0)} starts, {second_up.get('wins', 0)} wins ({second_up.get('winPercent', 0)*100:.1f}%) | | |
| ## Condition Performance | |
| | Condition | Starts | Wins | Win % | Place % | | |
| |-----------|--------|------|-------|---------| | |
| """ | |
| for cond_name, cond_data in sorted(cond_stats.items()): | |
| if cond_data.get('starts', 0) > 0: | |
| note += f"| {cond_name} | {cond_data.get('starts', 0)} | {cond_data.get('wins', 0)} | {cond_data.get('winPercent', 0)*100:.1f}% | {cond_data.get('placePercent', 0)*100:.1f}% |\n" | |
| note += f""" | |
| ## Last 20 Starts | |
| ``` | |
| {last20} | |
| ``` | |
| ## Form Analysis | |
| ``` | |
| {form} | |
| ``` | |
| ### Form Key | |
| - **1-3** = Finished in top 3 | |
| - **4-9** = Finished 4th-9th | |
| - **0** = Finished 10th or worse | |
| - **x** = Spell (not raced recently) | |
| - **f** = Fell | |
| - **p** = Pulled up | |
| --- | |
| ## Notes | |
| [Add your observations here] | |
| ## Related Horses | |
| [Link to related horses: sire, dam, stablemates] | |
| """ | |
| return note | |
| def generate_race_form_guide(race_data: dict, horses: list[dict]) -> str: | |
| """Generate comprehensive form guide for a race.""" | |
| date = race_data.get('date', '') | |
| track = race_data.get('track', '') | |
| race_num = race_data.get('raceNumber', 0) | |
| race_name = race_data.get('raceName', '') | |
| distance = race_data.get('distance', '') | |
| condition = race_data.get('condition', '') | |
| race_class = race_data.get('raceClass', '') | |
| prize = race_data.get('prizeMoney', '') | |
| start_time = race_data.get('startTime', '') | |
| num_runners = race_data.get('numberOfRunners', 0) | |
| note = f"""# {track} Race {race_num} — {date} | |
| ## Race Details | |
| - **Name**: {race_name} | |
| - **Distance**: {distance} | |
| - **Condition**: {condition} | |
| - **Class**: {race_class} | |
| - **Prize**: {prize} | |
| - **Start**: {start_time} | |
| - **Runners**: {num_runners} | |
| ## Form Guide | |
| | # | Horse | Jockey | Wgt | Barrier | Form | Win% | Place% | Track Win% | Dist Win% | | |
| |---|-------|--------|-----|---------|------|------|--------|------------|-----------| | |
| """ | |
| for horse in horses: | |
| stats = horse.get('stats', {}) | |
| overall = stats.get('overall', {}) | |
| track = stats.get('track', {}) | |
| distance = stats.get('distance', {}) | |
| note += f"| {horse['number']} | [[{horse['name']}]] | {horse.get('jockey', '')} | {horse.get('weight', 0)}kg | {horse.get('barrier', 0)} | {horse.get('form', '')} | {overall.get('winPercent', 0)*100:.1f}% | {overall.get('placePercent', 0)*100:.1f}% | {track.get('winPercent', 0)*100:.1f}% | {distance.get('winPercent', 0)*100:.1f}% |\n" | |
| note += """ | |
| ## Result | |
| [Add official result here] | |
| ## Analysis | |
| [Add race analysis here] | |
| """ | |
| return note | |
| def main(): | |
| date = "2026-08-15" | |
| print(f"Generating comprehensive form guides for {date}...") | |
| print("=" * 60) | |
| ensure_dirs() | |
| # Load all cached races | |
| races = load_all_cached_races(date) | |
| print(f"Loaded {len(races)} races") | |
| total_horses = 0 | |
| total_races = 0 | |
| for race_data in races: | |
| track = race_data.get('track', '') | |
| race_num = race_data.get('raceNumber', 0) | |
| # Extract horses | |
| horses = [] | |
| for r in race_data.get('runners', []): | |
| if r.get('scratched'): | |
| continue | |
| stats = r.get('stats', {}) | |
| overall = stats.get('overall', {}) | |
| track_stats = stats.get('track', {}) | |
| distance = stats.get('distance', {}) | |
| track_dist = stats.get('trackDistance', {}) | |
| cond_stats = stats.get('conditions', {}) | |
| first_up = stats.get('firstUp', {}) | |
| second_up = stats.get('secondUp', {}) | |
| # Get condition-specific stats | |
| cond_key = None | |
| for key in cond_stats: | |
| if cond_stats[key].get('starts', 0) > 0: | |
| cond_key = key | |
| break | |
| cond_data = cond_stats.get(cond_key, {}) if cond_key else {} | |
| horse = { | |
| 'number': r['number'], | |
| 'name': r.get('name', 'Unknown'), | |
| 'jockey': r.get('jockey', ''), | |
| 'trainer': r.get('trainer', ''), | |
| 'weight': r.get('weight', 0), | |
| 'barrier': r.get('barrier', 0), | |
| 'age': r.get('age', 0), | |
| 'sex': r.get('sex', ''), | |
| 'sire': r.get('sire', ''), | |
| 'dam': r.get('dam', ''), | |
| 'form': r.get('form', ''), | |
| 'last20_starts': r.get('last20Starts', ''), | |
| 'career_prize_money': r.get('careerPrizeMoney', '$0'), | |
| 'stats': { | |
| 'overall': { | |
| 'starts': overall.get('starts', 0), | |
| 'wins': overall.get('wins', 0), | |
| 'places': overall.get('places', 0), | |
| 'winPercent': overall.get('winPercent', 0), | |
| 'placePercent': overall.get('placePercent', 0), | |
| }, | |
| 'track': { | |
| 'starts': track_stats.get('starts', 0), | |
| 'wins': track_stats.get('wins', 0), | |
| 'winPercent': track_stats.get('winPercent', 0), | |
| 'placePercent': track_stats.get('placePercent', 0), | |
| }, | |
| 'distance': { | |
| 'starts': distance.get('starts', 0), | |
| 'wins': distance.get('wins', 0), | |
| 'winPercent': distance.get('winPercent', 0), | |
| 'placePercent': distance.get('placePercent', 0), | |
| }, | |
| 'trackDistance': { | |
| 'starts': track_dist.get('starts', 0), | |
| 'wins': track_dist.get('wins', 0), | |
| 'winPercent': track_dist.get('winPercent', 0), | |
| 'placePercent': track_dist.get('placePercent', 0), | |
| }, | |
| 'condition': { | |
| 'starts': cond_data.get('starts', 0), | |
| 'wins': cond_data.get('wins', 0), | |
| 'winPercent': cond_data.get('winPercent', 0), | |
| 'placePercent': cond_data.get('placePercent', 0), | |
| }, | |
| 'firstUp': { | |
| 'starts': first_up.get('starts', 0), | |
| 'wins': first_up.get('wins', 0), | |
| 'winPercent': first_up.get('winPercent', 0), | |
| }, | |
| 'secondUp': { | |
| 'starts': second_up.get('starts', 0), | |
| 'wins': second_up.get('wins', 0), | |
| 'winPercent': second_up.get('winPercent', 0), | |
| }, | |
| 'conditions': cond_stats, | |
| }, | |
| } | |
| horses.append(horse) | |
| if not horses: | |
| continue | |
| # Generate race form guide | |
| race_guide = generate_race_form_guide(race_data, horses) | |
| race_file = FORM_GUIDES_DIR / f"{date}-{track}-R{race_num}.md" | |
| with open(race_file, 'w') as f: | |
| f.write(race_guide) | |
| total_races += 1 | |
| total_horses += len(horses) | |
| # Generate individual horse form guides | |
| for horse in horses: | |
| horse_guide = generate_horse_form_guide(horse) | |
| horse_file = FORM_GUIDES_DIR / f"{date}-{horse['name'].replace(' ', '-')}.md" | |
| with open(horse_file, 'w') as f: | |
| f.write(horse_guide) | |
| print(f"Generated {total_races} race form guides") | |
| print(f"Generated {total_horses} horse form guides") | |
| print(f"Saved to: {FORM_GUIDES_DIR}") | |
| print("=" * 60) | |
| print("Complete!") | |
| if __name__ == "__main__": | |
| main() | |