""" Constructive Scenario Formatter Formats scenarios in an educational, constructive way """ from typing import List from ..database.scenario_models import ADASScenario, RankedScenario class FormattedScenario: """Formatted scenario""" def __init__( self, title: str, adas_feature: str, boundary_conditions: List[str], appropriate_responses: List[str], educational_principle: str, relevance_hint: str = "", full_scenario_link: str = "" ): self.title = title self.adas_feature = adas_feature self.boundary_conditions = boundary_conditions self.appropriate_responses = appropriate_responses self.educational_principle = educational_principle self.relevance_hint = relevance_hint self.full_scenario_link = full_scenario_link class ConstructiveFormatter: """Constructive scenario formatter""" def format_scenario(self, ranked_scenario: RankedScenario) -> FormattedScenario: """ Format a single scenario Principles: - Avoid detailed incident descriptions - Emphasize boundary conditions and appropriate responses - Provide educational principles - Use positive, constructive language """ scenario = ranked_scenario.scenario # Format boundary conditions boundary_conditions = self._format_boundary_conditions(scenario) # Format appropriate responses appropriate_responses = self._format_responses(scenario) # Extract educational principle educational_principle = self._format_principle(scenario) # Generate relevance hint relevance_hint = self._generate_relevance_hint(ranked_scenario) return FormattedScenario( title=scenario.title, adas_feature=scenario.adas_feature, boundary_conditions=boundary_conditions, appropriate_responses=appropriate_responses, educational_principle=educational_principle, relevance_hint=relevance_hint, full_scenario_link=f"/scenario/{scenario.scenario_id}" ) def _format_boundary_conditions(self, scenario: ADASScenario) -> List[str]: """Format boundary conditions using constructive language""" formatted = [] for bc in scenario.boundary_conditions: # Use constructive language: emphasize "may" rather than "failed" condition_text = f"• {bc.condition}: {bc.impact}" if bc.details: condition_text += f" ({bc.details})" formatted.append(condition_text) return formatted def _format_responses(self, scenario: ADASScenario) -> List[str]: """Format appropriate responses, emphasizing correct actions""" formatted = [] for ar in scenario.appropriate_responses: response_text = f"• {ar.response}: {ar.rationale}" if ar.details: response_text += f" ({ar.details})" formatted.append(response_text) return formatted def _format_principle(self, scenario: ADASScenario) -> str: """Format educational principle""" if scenario.educational_principles: # Use first principle, or combine multiple principles if len(scenario.educational_principles) == 1: return scenario.educational_principles[0] else: return " ".join(scenario.educational_principles[:2]) # Max two principles elif scenario.generalization: return scenario.generalization else: return "Understanding system limitations helps ensure safe operation." def _generate_relevance_hint(self, ranked_scenario: RankedScenario) -> str: """Generate relevance hint""" if ranked_scenario.match_reasons: reasons = ", ".join(ranked_scenario.match_reasons[:2]) # Max two reasons return f"Relevant because: {reasons}" return "" def format_scenarios_for_ui(self, ranked_scenarios: List[RankedScenario]) -> str: """ Format multiple scenarios as HTML for UI display Returns: str: HTML formatted scenario cards """ if not ranked_scenarios: return "" formatted_scenarios = [self.format_scenario(rs) for rs in ranked_scenarios] html_parts = [] for i, fs in enumerate(formatted_scenarios, 1): scenario_html = f"""
Related to: {fs.adas_feature}
{fs.educational_principle}
{fs.relevance_hint}
' if fs.relevance_hint else ''}