File size: 7,671 Bytes
e55d607
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import re
from typing import Dict, List, Any

class QuizValidator:
    """Validerer kvaliteten på genererte quiz-spørsmål"""
    
    def validate_question(self, question: Dict[str, Any]) -> Dict[str, Any]:
        """Valider et enkelt quiz-spørsmål"""
        
        issues = []
        score = 0
        max_score = 10
        
        # Sjekk grunnleggende struktur (4 poeng)
        if self._has_valid_question(question.get("spørsmål", "")):
            score += 1
        else:
            issues.append("Spørsmål mangler eller er for kort")
        
        if self._has_valid_alternatives(question.get("alternativer", [])):
            score += 1
        else:
            issues.append("Må ha nøyaktig 4 alternativer")
        
        if self._has_valid_correct_answer(question.get("korrekt_svar"), question.get("alternativer", [])):
            score += 1
        else:
            issues.append("Ugyldig korrekt svar-indeks")
        
        if self._has_valid_explanation(question.get("forklaring", "")):
            score += 1
        else:
            issues.append("Forklaring mangler eller er for kort")
        
        # Sjekk innholdskvalitet (3 poeng)
        content_score = self._assess_content_quality(question)
        score += content_score
        if content_score < 2:
            issues.append("Lav innholdskvalitet")
        
        # Sjekk språkkvalitet (2 poeng)
        language_score = self._assess_language_quality(question)
        score += language_score
        if language_score < 1:
            issues.append("Språklige problemer")
        
        # Sjekk logikk (1 poeng)
        if self._has_logical_consistency(question):
            score += 1
        else:
            issues.append("Logiske problemer med spørsmål/svar")
        
        return {
            "valid": score >= 7,  # Minimum 70% score
            "score": score,
            "max_score": max_score,
            "percentage": round((score / max_score) * 100, 1),
            "issues": issues
        }
    
    def _has_valid_question(self, question: str) -> bool:
        """Sjekk om spørsmålet er gyldig"""
        return (
            isinstance(question, str) and
            len(question.strip()) >= 10 and
            question.strip().endswith("?")
        )
    
    def _has_valid_alternatives(self, alternatives: List[str]) -> bool:
        """Sjekk om alternativene er gyldige"""
        return (
            isinstance(alternatives, list) and
            len(alternatives) == 4 and
            all(isinstance(alt, str) and len(alt.strip()) > 0 for alt in alternatives)
        )
    
    def _has_valid_correct_answer(self, correct_answer: int, alternatives: List[str]) -> bool:
        """Sjekk om korrekt svar er gyldig"""
        return (
            isinstance(correct_answer, int) and
            0 <= correct_answer < len(alternatives)
        )
    
    def _has_valid_explanation(self, explanation: str) -> bool:
        """Sjekk om forklaringen er gyldig"""
        return (
            isinstance(explanation, str) and
            len(explanation.strip()) >= 10
        )
    
    def _assess_content_quality(self, question: Dict[str, Any]) -> int:
        """Vurder innholdskvalitet (0-3 poeng)"""
        score = 0
        
        # Sjekk om spørsmålet er spesifikt nok
        question_text = question.get("spørsmål", "").lower()
        if any(word in question_text for word in ["hvilken", "hvilket", "hvem", "når", "hvor"]):
            score += 1
        
        # Sjekk om alternativene er rimelige
        alternatives = question.get("alternativer", [])
        if len(set(alt.lower() for alt in alternatives)) == len(alternatives):  # Unike alternativer
            score += 1
        
        # Sjekk om forklaringen er informativ
        explanation = question.get("forklaring", "")
        if len(explanation) > 30 and any(word in explanation.lower() for word in ["fordi", "siden", "på grunn av", "because"]):
            score += 1
        
        return score
    
    def _assess_language_quality(self, question: Dict[str, Any]) -> int:
        """Vurder språkkvalitet (0-2 poeng)"""
        score = 0
        
        # Sjekk for norske ord (enkel heuristikk)
        all_text = f"{question.get('spørsmål', '')} {' '.join(question.get('alternativer', []))} {question.get('forklaring', '')}"
        norwegian_indicators = ["og", "er", "i", "på", "av", "til", "for", "med", "det", "som", "en", "et", "den", "de"]
        
        if any(word in all_text.lower() for word in norwegian_indicators):
            score += 1
        
        # Sjekk for riktig tegnsetting
        if question.get("spørsmål", "").strip().endswith("?"):
            score += 1
        
        return score
    
    def _has_logical_consistency(self, question: Dict[str, Any]) -> bool:
        """Sjekk logisk konsistens"""
        try:
            correct_idx = question.get("korrekt_svar", -1)
            alternatives = question.get("alternativer", [])
            
            if 0 <= correct_idx < len(alternatives):
                correct_answer = alternatives[correct_idx]
                explanation = question.get("forklaring", "").lower()
                
                # Enkel sjekk: korrekt svar bør nevnes i forklaringen
                return correct_answer.lower() in explanation
            
            return False
        except:
            return False

    def validate_quiz_batch(self, questions: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Valider en hel batch med quiz-spørsmål"""
        
        if not questions:
            return {
                "valid": False,
                "overall_score": 0,
                "message": "Ingen spørsmål å validere",
                "question_results": []
            }
        
        results = []
        total_score = 0
        
        for i, question in enumerate(questions):
            validation = self.validate_question(question)
            validation["question_index"] = i
            results.append(validation)
            total_score += validation["score"]
        
        overall_score = total_score / (len(questions) * 10) * 100  # Prosent av maksimal score
        
        # Kategoriser kvalitet
        if overall_score >= 80:
            quality_level = "Utmerket"
        elif overall_score >= 70:
            quality_level = "God"
        elif overall_score >= 60:
            quality_level = "Akseptabel"
        else:
            quality_level = "Trenger forbedring"
        
        return {
            "valid": overall_score >= 70,
            "overall_score": round(overall_score, 1),
            "quality_level": quality_level,
            "total_questions": len(questions),
            "valid_questions": sum(1 for r in results if r["valid"]),
            "question_results": results,
            "summary": {
                "avg_score": round(total_score / len(questions), 1),
                "max_possible": 10,
                "common_issues": self._get_common_issues(results)
            }
        }
    
    def _get_common_issues(self, results: List[Dict[str, Any]]) -> List[str]:
        """Finn de vanligste problemene på tvers av spørsmål"""
        issue_counts = {}
        
        for result in results:
            for issue in result.get("issues", []):
                issue_counts[issue] = issue_counts.get(issue, 0) + 1
        
        # Returner issues som forekommer i mer enn 25% av spørsmålene
        threshold = len(results) * 0.25
        common_issues = [issue for issue, count in issue_counts.items() if count >= threshold]
        
        return common_issues