File size: 6,413 Bytes
6a11527
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""

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"""

            <div style="margin-bottom: 20px; padding: 15px; border: 1px solid #ddd; border-radius: 8px; background-color: #f9f9f9;">

                <h4 style="margin-top: 0; color: #333;">{fs.title}</h4>

                <p style="margin: 5px 0; color: #666; font-size: 0.9em;">Related to: <strong>{fs.adas_feature}</strong></p>

                

                <div style="margin: 15px 0;">

                    <strong style="color: #d9534f;">⚠️ Boundary Conditions:</strong>

                    <ul style="margin: 5px 0; padding-left: 20px;">

                        {''.join(f'<li style="margin: 5px 0;">{bc}</li>' for bc in fs.boundary_conditions)}

                    </ul>

                </div>

                

                <div style="margin: 15px 0;">

                    <strong style="color: #5cb85c;">βœ… Appropriate Responses:</strong>

                    <ul style="margin: 5px 0; padding-left: 20px;">

                        {''.join(f'<li style="margin: 5px 0;">{ar}</li>' for ar in fs.appropriate_responses)}

                    </ul>

                </div>

                

                <div style="margin: 15px 0;">

                    <strong style="color: #337ab7;">πŸ“– Educational Principle:</strong>

                    <p style="margin: 5px 0; font-style: italic;">{fs.educational_principle}</p>

                </div>

                

                {f'<p style="margin: 5px 0; font-size: 0.85em; color: #999;">{fs.relevance_hint}</p>' if fs.relevance_hint else ''}

            </div>

            """
            html_parts.append(scenario_html)
        
        return "".join(html_parts)