mirror of
https://github.com/ChrisSewell/LeosShoes.git
synced 2025-07-01 10:07:27 -04:00
Add 12/24 hour time format option and clean up test files
This commit is contained in:
8
.cursor/rules/byterover-rules.mdc
Normal file
8
.cursor/rules/byterover-rules.mdc
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
description: ByteRover MCP Custom Instructions
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# important
|
||||
always use search-memories tool to get the related context before any tasks
|
||||
always use create-memories to store all the critical informations after sucessfull tasks
|
@ -30,6 +30,9 @@ class RiskConfig:
|
||||
enable_graduated_recovery: bool = True
|
||||
enable_time_of_day_factor: bool = True
|
||||
|
||||
# Display preferences
|
||||
use_24hr_time: bool = False # False for 12hr time format, True for 24hr
|
||||
|
||||
@classmethod
|
||||
def from_env(cls) -> 'RiskConfig':
|
||||
"""Create configuration from environment variables."""
|
||||
@ -48,7 +51,9 @@ class RiskConfig:
|
||||
surface_type=os.getenv('SURFACE_TYPE', 'asphalt'),
|
||||
surface_max_recovery_score=float(os.getenv('SURFACE_MAX_RECOVERY_SCORE', 2.0)),
|
||||
enable_graduated_recovery=os.getenv('ENABLE_GRADUATED_RECOVERY', 'true').lower() == 'true',
|
||||
enable_time_of_day_factor=os.getenv('ENABLE_TIME_OF_DAY_FACTOR', 'true').lower() == 'true'
|
||||
enable_time_of_day_factor=os.getenv('ENABLE_TIME_OF_DAY_FACTOR', 'true').lower() == 'true',
|
||||
# Display preferences
|
||||
use_24hr_time=os.getenv('USE_24HR_TIME', 'false').lower() == 'true'
|
||||
)
|
||||
|
||||
@dataclass
|
||||
|
@ -33,3 +33,6 @@ SURFACE_TYPE=asphalt
|
||||
SURFACE_MAX_RECOVERY_SCORE=2.0
|
||||
ENABLE_GRADUATED_RECOVERY=true
|
||||
ENABLE_TIME_OF_DAY_FACTOR=true
|
||||
|
||||
# Display preferences (Optional)
|
||||
USE_24HR_TIME=false
|
14
main.py
14
main.py
@ -71,6 +71,13 @@ class PawRiskApp:
|
||||
logger.error(f"Error during analysis: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
def format_time(self, dt: datetime) -> str:
|
||||
"""Format time based on user's preference."""
|
||||
if self.config.risk_config.use_24hr_time:
|
||||
return dt.strftime("%H:%M")
|
||||
else:
|
||||
return dt.strftime("%I:%M %p")
|
||||
|
||||
def print_summary(self, analysis_result: dict):
|
||||
"""Print a formatted summary of the analysis."""
|
||||
if "error" in analysis_result:
|
||||
@ -117,11 +124,11 @@ class PawRiskApp:
|
||||
|
||||
print("\n🕐 HOURLY BREAKDOWN:")
|
||||
print("-" * 80)
|
||||
print(f"{'Time':>6} {'Temp':>6} {'UV':>4} {'Condition':>12} {'Risk':>6} {'Shoes':>7}")
|
||||
print(f"{'Time':>8} {'Temp':>6} {'UV':>4} {'Condition':>12} {'Risk':>6} {'Shoes':>7}")
|
||||
print("-" * 80)
|
||||
|
||||
for weather, risk in zip(weather_hours, risk_scores):
|
||||
time_str = weather.datetime.strftime("%H:%M")
|
||||
time_str = self.format_time(weather.datetime)
|
||||
temp_str = f"{weather.temperature_f:.0f}°F"
|
||||
uv_str = f"{weather.uv_index:.1f}" if weather.uv_index else "N/A"
|
||||
condition_short = weather.condition[:12]
|
||||
@ -129,7 +136,7 @@ class PawRiskApp:
|
||||
shoes_str = "YES" if risk.recommend_shoes else "no"
|
||||
shoes_color = "⚠️ " if risk.recommend_shoes else "✅ "
|
||||
|
||||
print(f"{time_str:>6} {temp_str:>6} {uv_str:>4} {condition_short:>12} "
|
||||
print(f"{time_str:>8} {temp_str:>6} {uv_str:>4} {condition_short:>12} "
|
||||
f"{risk_str:>6} {shoes_color}{shoes_str:>5}")
|
||||
|
||||
def create_plots(self, analysis_result: dict, save_plots: bool = False):
|
||||
@ -207,6 +214,7 @@ def main():
|
||||
print(f"Default Location: {config.default_location}")
|
||||
print(f"Database Path: {config.database_path}")
|
||||
print(f"Risk Threshold: {config.risk_config.risk_threshold_shoes}")
|
||||
print(f"Time Format: {'24-hour' if config.risk_config.use_24hr_time else '12-hour'}")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"❌ Configuration error: {e}")
|
||||
|
26
plotting.py
26
plotting.py
@ -10,6 +10,7 @@ import warnings
|
||||
import os
|
||||
import shutil
|
||||
from models import WeatherHour, RiskScore
|
||||
from config import RiskConfig, get_config
|
||||
|
||||
# Suppress matplotlib UserWarnings and macOS GUI warnings
|
||||
warnings.filterwarnings('ignore', category=UserWarning, module='matplotlib')
|
||||
@ -18,16 +19,30 @@ warnings.filterwarnings('ignore', message='.*NSSavePanel.*')
|
||||
class RiskPlotter:
|
||||
"""Handles plotting and visualization of risk data."""
|
||||
|
||||
def __init__(self, figure_size: Tuple[int, int] = (12, 8)):
|
||||
def __init__(self, figure_size: Tuple[int, int] = (12, 8), use_24hr_time: Optional[bool] = None):
|
||||
self.figure_size = figure_size
|
||||
self.plots_dir = "plots"
|
||||
self._plots_dir_setup = False
|
||||
|
||||
# Get time format preference from config if not specified
|
||||
if use_24hr_time is None:
|
||||
config = get_config().risk_config
|
||||
self.use_24hr_time = getattr(config, 'use_24hr_time', False)
|
||||
else:
|
||||
self.use_24hr_time = use_24hr_time
|
||||
|
||||
# Set up matplotlib style and suppress warnings
|
||||
plt.style.use('default')
|
||||
plt.rcParams['figure.figsize'] = figure_size
|
||||
plt.rcParams['font.size'] = 10
|
||||
|
||||
def get_time_formatter(self):
|
||||
"""Get the appropriate time formatter based on config."""
|
||||
if self.use_24hr_time:
|
||||
return mdates.DateFormatter('%H:%M')
|
||||
else:
|
||||
return mdates.DateFormatter('%I:%M %p')
|
||||
|
||||
def _setup_plots_directory(self):
|
||||
"""Create and clear plots directory."""
|
||||
if os.path.exists(self.plots_dir):
|
||||
@ -116,8 +131,9 @@ class RiskPlotter:
|
||||
ax3.grid(True, alpha=0.3)
|
||||
|
||||
# Format x-axis
|
||||
time_formatter = self.get_time_formatter()
|
||||
for ax in [ax1, ax2, ax3]:
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
|
||||
ax.xaxis.set_major_formatter(time_formatter)
|
||||
ax.xaxis.set_major_locator(mdates.HourLocator(interval=2))
|
||||
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
|
||||
|
||||
@ -166,7 +182,8 @@ class RiskPlotter:
|
||||
ax.grid(True, alpha=0.3)
|
||||
|
||||
# Format x-axis
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
|
||||
time_formatter = self.get_time_formatter()
|
||||
ax.xaxis.set_major_formatter(time_formatter)
|
||||
ax.xaxis.set_major_locator(mdates.HourLocator(interval=2))
|
||||
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
|
||||
|
||||
@ -334,8 +351,9 @@ class RiskPlotter:
|
||||
ax4.set_title('Weather Conditions')
|
||||
|
||||
# Format x-axis for all subplots
|
||||
time_formatter = self.get_time_formatter()
|
||||
for ax in [ax1, ax4]:
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
|
||||
ax.xaxis.set_major_formatter(time_formatter)
|
||||
ax.xaxis.set_major_locator(mdates.HourLocator(interval=2))
|
||||
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
|
||||
|
||||
|
@ -303,6 +303,13 @@ class RiskCalculator:
|
||||
|
||||
return blocks
|
||||
|
||||
def format_time(self, dt: datetime) -> str:
|
||||
"""Format time based on user's preference."""
|
||||
if hasattr(self.config, 'use_24hr_time') and self.config.use_24hr_time:
|
||||
return dt.strftime("%H:%M")
|
||||
else:
|
||||
return dt.strftime("%I:%M %p")
|
||||
|
||||
def generate_recommendations(self, risk_scores: List[RiskScore]) -> dict:
|
||||
"""Generate comprehensive recommendations based on risk scores."""
|
||||
if not risk_scores:
|
||||
@ -326,13 +333,13 @@ class RiskCalculator:
|
||||
"high_risk_hours": high_risk_hours,
|
||||
"max_risk_score": round(max_score, 1),
|
||||
"average_risk_score": round(avg_score, 1),
|
||||
"peak_risk_time": peak_score.datetime.strftime("%H:%M"),
|
||||
"peak_risk_time": self.format_time(peak_score.datetime),
|
||||
"continuous_risk_blocks": len(risk_blocks)
|
||||
},
|
||||
"risk_periods": [
|
||||
{
|
||||
"start": start.strftime("%H:%M"),
|
||||
"end": end.strftime("%H:%M"),
|
||||
"start": self.format_time(start),
|
||||
"end": self.format_time(end),
|
||||
"duration_hours": round((end - start).total_seconds() / 3600, 1)
|
||||
}
|
||||
for start, end in risk_blocks
|
||||
|
@ -1,154 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for enhanced surface recovery logic with real data
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import matplotlib.pyplot as plt
|
||||
from datetime import datetime, timedelta
|
||||
from models import WeatherHour, RiskScore
|
||||
from config import RiskConfig, AppConfig, get_config
|
||||
from risk_calculator import RiskCalculator
|
||||
from constants import SURFACE_COOLING_COEFFICIENTS
|
||||
from models import DatabaseManager
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def load_db_data():
|
||||
"""Load real weather data from the database."""
|
||||
config = get_config()
|
||||
db_manager = DatabaseManager(config.database_path)
|
||||
|
||||
# Get data from the past 24 hours
|
||||
end_date = datetime.now()
|
||||
start_date = end_date - timedelta(hours=24)
|
||||
|
||||
try:
|
||||
return db_manager.get_weather_data(start_date, end_date)
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading data from database: {e}")
|
||||
return []
|
||||
|
||||
def compare_recovery_settings(weather_data):
|
||||
"""Compare different recovery settings with real weather data."""
|
||||
if not weather_data:
|
||||
logger.error("No weather data available for testing")
|
||||
return
|
||||
|
||||
print(f"Loaded {len(weather_data)} hours of weather data from database")
|
||||
print(f"Temperature range: {min(h.temperature_f for h in weather_data):.1f}°F - {max(h.temperature_f for h in weather_data):.1f}°F")
|
||||
|
||||
# Test configs
|
||||
configs = [
|
||||
# Default settings
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=False,
|
||||
enable_time_of_day_factor=False
|
||||
),
|
||||
# All enhanced features
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=True,
|
||||
enable_time_of_day_factor=True,
|
||||
surface_max_recovery_score=2.0,
|
||||
surface_type="asphalt"
|
||||
),
|
||||
]
|
||||
|
||||
# Test each configuration
|
||||
all_results = []
|
||||
|
||||
for i, config in enumerate(configs):
|
||||
calculator = RiskCalculator(config)
|
||||
risk_scores = calculator.calculate_risk_scores(weather_data)
|
||||
all_results.append(risk_scores)
|
||||
|
||||
label = "Default" if i == 0 else "Enhanced"
|
||||
print(f"\n=== {label} Recovery Settings ===")
|
||||
|
||||
high_risk = [s for s in risk_scores if s.recommend_shoes]
|
||||
print(f"High Risk Hours: {len(high_risk)} out of {len(risk_scores)}")
|
||||
|
||||
if high_risk:
|
||||
times = [s.datetime.strftime("%H:%M") for s in high_risk]
|
||||
print(f"High Risk Times: {', '.join(times)}")
|
||||
|
||||
# Show recovery score impact
|
||||
recovery_impact = sum(abs(s.surface_recovery_score) for s in risk_scores)
|
||||
print(f"Total Recovery Impact: {recovery_impact:.2f}")
|
||||
print(f"Average Recovery Score: {recovery_impact/len(risk_scores):.2f}")
|
||||
|
||||
# Visualize the results
|
||||
visualize_comparison(weather_data, all_results)
|
||||
|
||||
def visualize_comparison(weather_data, result_sets):
|
||||
"""Create visualization comparing different recovery strategies with real data."""
|
||||
plt.figure(figsize=(14, 10))
|
||||
|
||||
# Extract time and temperatures for plotting
|
||||
times = [hour.datetime for hour in weather_data]
|
||||
temps = [hour.temperature_f for hour in weather_data]
|
||||
|
||||
# Plot temperature
|
||||
ax1 = plt.subplot(3, 1, 1)
|
||||
ax1.plot(times, temps, 'r-', linewidth=2)
|
||||
ax1.set_ylabel('Temperature (°F)')
|
||||
ax1.set_title('Temperature Profile')
|
||||
ax1.axhline(y=90, color='r', linestyle='--', alpha=0.7)
|
||||
ax1.text(times[0], 91, "Recovery Threshold (90°F)", color='r')
|
||||
ax1.grid(True, alpha=0.3)
|
||||
|
||||
# Plot recovery scores
|
||||
ax2 = plt.subplot(3, 1, 2, sharex=ax1)
|
||||
|
||||
# Add labels for legend
|
||||
labels = ['Default Recovery', 'Enhanced Recovery']
|
||||
linestyles = ['-', '--']
|
||||
colors = ['blue', 'green']
|
||||
|
||||
for i, results in enumerate(result_sets):
|
||||
recovery_scores = [score.surface_recovery_score for score in results]
|
||||
ax2.plot(times, recovery_scores, linestyle=linestyles[i], color=colors[i], linewidth=2, label=labels[i])
|
||||
|
||||
ax2.set_ylabel('Recovery Score')
|
||||
ax2.set_title('Surface Recovery Scores Comparison')
|
||||
ax2.grid(True, alpha=0.3)
|
||||
ax2.legend()
|
||||
|
||||
# Plot total risk scores
|
||||
ax3 = plt.subplot(3, 1, 3, sharex=ax1)
|
||||
|
||||
for i, results in enumerate(result_sets):
|
||||
total_scores = [score.total_score for score in results]
|
||||
ax3.plot(times, total_scores, linestyle=linestyles[i], color=colors[i], linewidth=2, label=labels[i])
|
||||
|
||||
# Add threshold line
|
||||
ax3.axhline(y=6.0, color='red', linestyle='--', alpha=0.7, label='Shoe Threshold (6.0)')
|
||||
|
||||
ax3.set_ylabel('Total Risk Score')
|
||||
ax3.set_title('Total Risk Score Comparison (Real Weather Data)')
|
||||
ax3.set_xlabel('Time')
|
||||
ax3.grid(True, alpha=0.3)
|
||||
ax3.legend()
|
||||
|
||||
# Format x-axis
|
||||
for ax in [ax1, ax2, ax3]:
|
||||
ax.set_xlim(times[0], times[-1])
|
||||
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig('real_data_comparison.png')
|
||||
plt.show()
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Testing enhanced surface recovery logic with real data")
|
||||
weather_data = load_db_data()
|
||||
if weather_data:
|
||||
compare_recovery_settings(weather_data)
|
||||
else:
|
||||
print("No data available. Please ensure you've run the app to collect weather data first.")
|
199
test_recovery.py
199
test_recovery.py
@ -1,199 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for enhanced surface recovery logic
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from datetime import datetime, timedelta
|
||||
from models import WeatherHour
|
||||
from config import RiskConfig
|
||||
from risk_calculator import RiskCalculator
|
||||
from constants import SURFACE_COOLING_COEFFICIENTS
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def create_test_data():
|
||||
"""Create synthetic test data with a temperature peak followed by cooling."""
|
||||
now = datetime.now()
|
||||
hours = []
|
||||
|
||||
# Create a 24-hour dataset
|
||||
for i in range(24):
|
||||
# Time starting from 24 hours ago to now
|
||||
time = now - timedelta(hours=24-i)
|
||||
|
||||
# Temperature pattern: starts low, peaks in afternoon, drops at night
|
||||
if i < 8: # Early morning (cold)
|
||||
temp = 75.0 + i * 1.5
|
||||
condition = "Clear"
|
||||
uv = 0.0
|
||||
elif i < 14: # Mid-day heating (peak at 2pm / hour 14)
|
||||
temp = 85.0 + (i - 8) * 3.0
|
||||
condition = "Sunny"
|
||||
uv = 8.0
|
||||
else: # Afternoon cooling
|
||||
temp = 95.0 - (i - 14) * 2.0
|
||||
condition = "Partly Cloudy" if i < 18 else "Clear"
|
||||
uv = max(0.0, 8.0 - (i - 14) * 1.5)
|
||||
|
||||
# Create a peak temperature that exceeds threshold
|
||||
if i == 13: # 1pm
|
||||
temp = 95.0 # Peak temperature
|
||||
|
||||
hours.append(WeatherHour(
|
||||
datetime=time,
|
||||
temperature_f=temp,
|
||||
uv_index=uv,
|
||||
condition=condition,
|
||||
is_forecast=False
|
||||
))
|
||||
|
||||
return hours
|
||||
|
||||
def visualize_results(test_data, all_results):
|
||||
"""Create visualization comparing different recovery strategies."""
|
||||
plt.figure(figsize=(14, 10))
|
||||
|
||||
# Extract time and temperatures for plotting
|
||||
times = [hour.datetime for hour in test_data]
|
||||
temps = [hour.temperature_f for hour in test_data]
|
||||
|
||||
# Plot temperature
|
||||
ax1 = plt.subplot(3, 1, 1)
|
||||
ax1.plot(times, temps, 'r-', linewidth=2)
|
||||
ax1.set_ylabel('Temperature (°F)')
|
||||
ax1.set_title('Temperature Profile')
|
||||
ax1.axhline(y=90, color='r', linestyle='--', alpha=0.7)
|
||||
ax1.text(times[0], 91, "Recovery Threshold (90°F)", color='r')
|
||||
ax1.grid(True, alpha=0.3)
|
||||
|
||||
# Plot recovery scores
|
||||
ax2 = plt.subplot(3, 1, 2, sharex=ax1)
|
||||
|
||||
# Add labels for legend
|
||||
labels = ['Default', 'Graduated', 'Time-of-day', 'All Features', 'Concrete', 'Grass']
|
||||
linestyles = ['-', '--', ':', '-.', '--', ':']
|
||||
colors = ['blue', 'green', 'purple', 'orange', 'brown', 'magenta']
|
||||
|
||||
for i, results in enumerate(all_results):
|
||||
recovery_scores = [score.surface_recovery_score for score in results]
|
||||
ax2.plot(times, recovery_scores, linestyle=linestyles[i], color=colors[i], linewidth=2, label=labels[i])
|
||||
|
||||
ax2.set_ylabel('Recovery Score')
|
||||
ax2.set_title('Surface Recovery Scores Comparison')
|
||||
ax2.grid(True, alpha=0.3)
|
||||
ax2.legend()
|
||||
|
||||
# Plot total risk scores
|
||||
ax3 = plt.subplot(3, 1, 3, sharex=ax1)
|
||||
|
||||
for i, results in enumerate(all_results):
|
||||
total_scores = [score.total_score for score in results]
|
||||
ax3.plot(times, total_scores, linestyle=linestyles[i], color=colors[i], linewidth=2, label=labels[i])
|
||||
|
||||
# Add threshold line
|
||||
ax3.axhline(y=6.0, color='red', linestyle='--', alpha=0.7, label='Shoe Threshold (6.0)')
|
||||
|
||||
ax3.set_ylabel('Total Risk Score')
|
||||
ax3.set_title('Total Risk Score Comparison')
|
||||
ax3.set_xlabel('Time')
|
||||
ax3.grid(True, alpha=0.3)
|
||||
ax3.legend()
|
||||
|
||||
# Format x-axis
|
||||
for ax in [ax1, ax2, ax3]:
|
||||
ax.set_xlim(times[0], times[-1])
|
||||
plt.setp(ax.xaxis.get_majorticklabels(), rotation=45)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig('recovery_comparison.png')
|
||||
plt.show()
|
||||
|
||||
def test_recovery_settings():
|
||||
"""Test different recovery settings and compare results."""
|
||||
test_data = create_test_data()
|
||||
|
||||
# Test configs
|
||||
configs = [
|
||||
# Default settings
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=False,
|
||||
enable_time_of_day_factor=False
|
||||
),
|
||||
# Graduated recovery
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=True,
|
||||
enable_time_of_day_factor=False,
|
||||
surface_max_recovery_score=2.0
|
||||
),
|
||||
# Time-of-day factor
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=False,
|
||||
enable_time_of_day_factor=True
|
||||
),
|
||||
# All features
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
enable_graduated_recovery=True,
|
||||
enable_time_of_day_factor=True,
|
||||
surface_max_recovery_score=2.0
|
||||
),
|
||||
# Different surface types
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
surface_type="concrete",
|
||||
enable_graduated_recovery=True,
|
||||
enable_time_of_day_factor=True
|
||||
),
|
||||
RiskConfig(
|
||||
surface_recovery_temp_threshold=90.0,
|
||||
surface_type="grass",
|
||||
enable_graduated_recovery=True,
|
||||
enable_time_of_day_factor=True
|
||||
),
|
||||
]
|
||||
|
||||
all_results = []
|
||||
|
||||
# Test each configuration
|
||||
for i, config in enumerate(configs):
|
||||
calculator = RiskCalculator(config)
|
||||
risk_scores = calculator.calculate_risk_scores(test_data)
|
||||
all_results.append(risk_scores)
|
||||
|
||||
print(f"\n=== Test Config {i+1} ===")
|
||||
print(f"Surface Type: {config.surface_type}")
|
||||
print(f"Graduated Recovery: {config.enable_graduated_recovery}")
|
||||
print(f"Time-of-Day Factor: {config.enable_time_of_day_factor}")
|
||||
|
||||
print("\nHourly Surface Recovery Scores:")
|
||||
print("Hour | Temp | Recovery Score")
|
||||
print("-" * 30)
|
||||
|
||||
for hour, score in enumerate(risk_scores):
|
||||
temp = test_data[hour].temperature_f
|
||||
time = test_data[hour].datetime.strftime("%H:%M")
|
||||
print(f"{time} | {temp:4.1f}°F | {score.surface_recovery_score:5.2f}")
|
||||
|
||||
# Show the highest risk hours
|
||||
high_risk = [s for s in risk_scores if s.recommend_shoes]
|
||||
print(f"\nHigh Risk Hours: {len(high_risk)} out of {len(risk_scores)}")
|
||||
if high_risk:
|
||||
times = [s.datetime.strftime("%H:%M") for s in high_risk]
|
||||
print(f"Times: {', '.join(times)}")
|
||||
|
||||
# Visualize comparison
|
||||
visualize_results(test_data, all_results)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Testing enhanced surface recovery logic")
|
||||
test_recovery_settings()
|
Reference in New Issue
Block a user