diff --git a/.Jules/palette.md b/.Jules/palette.md index e565b3e..e2beb07 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -5,6 +5,7 @@ ## 2025-02-28 - Structured CLI Reports **Learning:** Dense numerical data in CLI output is hard to parse. Using ASCII box-drawing characters and alignment to create a "dashboard" or "invoice" style summary significantly improves readability and perceived quality. **Action:** When summarizing simulation or batch job results, always format the final report as a structured table or box rather than a list of print statements. -## 2024-05-20 - Dynamic Progress Bar for Quiet CLI Tasks -**Learning:** For long-running CLI processes that suppress verbose logging (e.g., `--quiet`), users lose system status visibility. -**Action:** Implemented a dynamic progress bar using `\r` and `flush=True`, conditional on `sys.stdout.isatty()`, to provide status feedback without polluting non-interactive logs. + +## 2025-03-14 - Dynamic Progress Bars in Quiet CLI Modes +**Learning:** For long-running CLI applications that support a `--quiet` flag (which normally suppresses verbose logging), providing a dynamic progress bar using `\r` and `flush=True` (conditional on `sys.stdout.isatty()`) offers a much better UX. It gives the user necessary status visibility during long executions without polluting non-interactive environments (like CI/CD) or file redirections. +**Action:** Always consider replacing suppressed verbose output with a dynamic progress bar for long-running scripts when `--quiet` mode is active and the terminal is interactive. diff --git a/bitcoin_trading_simulation.py b/bitcoin_trading_simulation.py index 0d46e73..cd6337b 100644 --- a/bitcoin_trading_simulation.py +++ b/bitcoin_trading_simulation.py @@ -84,14 +84,11 @@ def simulate_trading(signals, initial_cash=10000, quiet=False): if not quiet: print(f"\n{Colors.HEADER}{Colors.BOLD}------ Daily Trading Ledger ------{Colors.ENDC}") - for idx, (i, row) in enumerate(signals.iterrows()): - if quiet and sys.stdout.isatty(): - progress = (idx + 1) / len(signals) - bar_length = 30 - filled_len = int(bar_length * progress) - bar = '█' * filled_len + '-' * (bar_length - filled_len) - print(f'\r{Colors.BLUE}Simulation Progress: |{bar}| {progress:.1%}{Colors.ENDC}', end='', flush=True) + total_days = len(signals) + show_progress = quiet and sys.stdout.isatty() + + for idx, (i, row) in enumerate(signals.iterrows()): if i > 0: portfolio.loc[i, 'cash'] = portfolio.loc[i-1, 'cash'] portfolio.loc[i, 'btc'] = portfolio.loc[i-1, 'btc'] @@ -118,6 +115,15 @@ def simulate_trading(signals, initial_cash=10000, quiet=False): if not quiet: print(f"Day {i}: Portfolio Value: ${portfolio.loc[i, 'total_value']:.2f}, " f"Cash: ${portfolio.loc[i, 'cash']:.2f}, BTC: {portfolio.loc[i, 'btc']:.4f}") + elif show_progress: + progress = (idx + 1) / total_days + bar_length = 30 + filled_length = int(bar_length * progress) + bar = '█' * filled_length + '-' * (bar_length - filled_length) + print(f"\r{Colors.CYAN}Simulating: [{bar}] {progress:.0%}{Colors.ENDC}", end='', flush=True) + + if show_progress: + print() if quiet and sys.stdout.isatty(): print()