File size: 16,434 Bytes
4120158
53c52df
 
 
 
4120158
 
 
53c52df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4120158
 
53c52df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc39d32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53c52df
cc39d32
53c52df
cc39d32
53c52df
cc39d32
 
 
 
53c52df
cc39d32
53c52df
cc39d32
 
53c52df
 
cc39d32
53c52df
cc39d32
 
10ad0d4
53c52df
 
cc39d32
 
53c52df
 
 
cc39d32
53c52df
 
 
 
cc39d32
53c52df
 
 
 
 
 
 
 
 
 
cc39d32
53c52df
 
cc39d32
 
 
53c52df
 
 
 
142ee1e
cc39d32
142ee1e
cc39d32
53c52df
cc39d32
53c52df
 
 
cc39d32
53c52df
cc39d32
53c52df
cc39d32
53c52df
 
142ee1e
cc39d32
142ee1e
cc39d32
53c52df
cc39d32
53c52df
 
 
e16bafa
53c52df
cc39d32
53c52df
cc39d32
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
import streamlit as st
import requests
from bs4 import BeautifulSoup
from sentence_transformers import SentenceTransformer, util
import numpy as np



# Load an embedding model
@st.cache_resource
def load_model():
  return SentenceTransformer('mixedbread-ai/deepset-mxbai-embed-de-large-v1')

# Ideal answer for comparison
IDEAL_ANSWER = """
Das Weihnachtsfest in Deutschland ist geprägt von einer Vielzahl an Bräuchen, Symbolen und Traditionen, die regional unterschiedliche Ausprägungen haben.
Neben allgemeinen, landesweiten Traditionen existieren in den einzelnen Regionen eigene Bräuche, die das Weihnachtsfest besonders machen.

Allgemeine Bräuche und Symbole
Zu den bekanntesten Symbolen und Bräuchen, die landesweit verbreitet sind, zählen der Adventskranz, der Weihnachtsbaum, der Nikolaustag, der Weihnachtsmarkt sowie bestimmte kulinarische Spezialitäten.
Diese Traditionen schaffen eine festliche Atmosphäre und symbolisieren für viele Deutsche die Weihnachtszeit.

Advent und Adventskranz: Der Advent, die Vorbereitungszeit auf Weihnachten, beginnt am vierten Sonntag vor Weihnachten.
In dieser Zeit wird oft ein Adventskranz mit vier Kerzen aufgestellt, von denen jeden Sonntag eine weitere angezündet wird.
Dieser Brauch ist besonders im ganzen Land verbreitet und symbolisiert die wachsende Vorfreude auf das Fest.

Weihnachtsbaum: Der Weihnachtsbaum ist das zentrale Symbol des Weihnachtsfestes in Deutschland.
Meistens wird er am Heiligen Abend aufgestellt und mit Kerzen, Kugeln und manchmal auch selbstgebasteltem Schmuck dekoriert.
Der Brauch stammt ursprünglich aus dem Elsass und verbreitete sich im 19. Jahrhundert über ganz Deutschland.

Nikolaustag: Am 6. Dezember wird der Nikolaustag gefeiert. Kinder stellen am Abend vorher ihre Stiefel vor die Tür, die über Nacht vom „Nikolaus“ mit Süßigkeiten und kleinen Geschenken gefüllt werden.
Dieser Brauch ist in vielen Regionen verbreitet, zeigt jedoch in einigen Gebieten, besonders in Süddeutschland, Abweichungen, da dort oft der „Knecht Ruprecht“ oder „Krampus“ den Nikolaus begleitet.

Weihnachtsmärkte: Weihnachtsmärkte sind in Deutschland besonders beliebt und gehören zur Adventszeit.
Sie bieten regionale Spezialitäten, Weihnachtsdekoration und handgemachte Geschenke. Bekannte Weihnachtsmärkte gibt es in Städten wie Nürnberg, Dresden und München.
Diese Märkte variieren in ihrem Angebot und Charakter je nach Region, was besonders für Touristen attraktiv ist.

Weihnachtsessen: Traditionell wird am Heiligen Abend oft eine einfache Mahlzeit wie Kartoffelsalat mit Würstchen serviert, während das Festessen am ersten Weihnachtstag stattfindet.
Gänsebraten, Rotkohl und Klöße sind typische Speisen für das Weihnachtsessen. Auch hier gibt es regionale Unterschiede: Im Süden Deutschlands werden oft Bratwürste serviert, während im Norden Fischgerichte beliebter sind.

Regionale Unterschiede
Die regionalen Unterschiede beim Weihnachtsfest in Deutschland zeigen sich nicht nur in der Art der Bräuche, sondern auch in speziellen Traditionen:

Bayern und der Alpenraum: In Bayern und im Alpenraum gibt es besonders reichhaltige Bräuche. Hier ist das „Krippenspiel“ weit verbreitet, bei dem die Geburt Jesu in einem kleinen Theaterstück nachgestellt wird.
In vielen Dörfern und Städten findet auch das „Christkindl-Anschießen“ statt, bei dem Schützenvereine am Heiligen Abend Böllerschüsse abfeuern, um das Christkind willkommen zu heißen.

Norddeutschland: In Norddeutschland sind Weihnachtslieder und das Singen von Shanties, also traditionellen Seemannsliedern, häufig Teil der Festlichkeiten.
Auch die Dekoration unterscheidet sich leicht, mit einem stärkeren Fokus auf maritime Symbole. Der Weihnachtsmann braven Kindern am Heiligen Abend Geschenke.

Sachsen und das Erzgebirge: Sachsen, insbesondere das Erzgebirge, ist bekannt für seinen reich verzierten Weihnachtsschmuck und das Kunsthandwerk.
Schwibbögen, Räuchermännchen und Nussknacker sind Symbole dieser Region und stammen ursprünglich aus der Bergbaugeschichte des Erzgebirges, in der Licht eine besondere Rolle spielte.

Rheinland: Im Rheinland ist die Tradition des Sternsingens weit verbreitet. Kinder ziehen als „Heilige Drei Könige“ verkleidet von Haus zu Haus und singen Lieder, um Spenden für wohltätige Zwecke zu sammeln.
Diese Tradition wird zwar auch in anderen Teilen Deutschlands gepflegt, hat jedoch im Rheinland eine besonders lange Geschichte.
"""

KEYWORDS = [
    "Advent", "Adventskranz", "Weihnachtsbaum", "Nikolaus", "Weihnachtsmarkt", "Weihnachtsessen",
    "Weihnachtslieder", "Weihnachtsschmuck", "Krippenspiel", "Weihnachtsgebäck", "Bescherung", "Wichteln"
]

REGION_KEYWORDS = {
    "Süddeutschland": ["Christkind", "Krampus", "Böllerschüsse"],
    "Norddeutschland": ["Weihnachtsmann", "Weihnachtslieder"],
    "Ostdeutschland": ["Schwibbogen", "Weihnachtspyramide", "Nussknacker"],
    "Westdeutschland": ["Sternsingen", "Adventskalender"]
}

@st.cache_data
def get_ideal_embedding():
    model = load_model()
    return model.encode(IDEAL_ANSWER, convert_to_tensor=True)

# --- HELPER FUNCTIONS ---
def fetch_wikipedia_content(url):
  if "wikipedia.org" not in url:
        return None
  headers = {'User-Agent': 'EducationalSchoolProject/1.0'}
  try:
        response = requests.get(url, headers=headers, timeout=5)
        if response.status_code != 200:
            return None
            
        soup = BeautifulSoup(response.text, 'html.parser')
        
        content_div = soup.find('div', {'id': 'mw-content-text'})
        if content_div:
            paragraphs = content_div.find_all('p')
            content = ' '.join([para.text for para in paragraphs])
            return content
        return None
  except Exception as e:
        return None

def evaluate_contexts(student_texts):
    model = load_model()
    ideal_embedding = get_ideal_embedding()
    
    scores = {"relevance": [], "completeness": 0, "regional_completeness": 0}
    all_found_keywords = set()
    combined_text = " ".join(student_texts)

    for text in student_texts:
        student_embedding = model.encode(text, convert_to_tensor=True)
        relevance_score = util.cos_sim(student_embedding, ideal_embedding).item()
        scores["relevance"].append(relevance_score)

        found = [k for k in KEYWORDS if k.lower() in text.lower()]
        all_found_keywords.update(found)

    scores["relevance"] = np.mean(scores["relevance"]) if scores["relevance"] else 0
    scores["completeness"] = len(all_found_keywords) / len(KEYWORDS)

    regions_covered = 0
    total_regions = len(REGION_KEYWORDS)
    for region, words in REGION_KEYWORDS.items():
        if any(word.lower() in combined_text.lower() for word in words):
            regions_covered += 1      
    scores["regional_completeness"] = regions_covered / total_regions

    return scores

# --- STREAMLIT UI ---
TEXTS = {
    "Deutsch": {
        "page_title": "Weihnachts-Elf Trainer",
        "main_title": "🎄 Weihnachts-Traditionen: Kontextbewertung für KI",
        "task_header": "🎅 Aufgabe: Trainiere den Weihnachts-Elf",
        "task_desc_1": "Wir bauen einen KI-Agenten, der Touristen Fragen zu Weihnachten in Deutschland beantwortet. Aber: <strong>Der Elf weiß nur das, was DU ihm zu lesen gibst!</strong>",
        "task_desc_2": "Finde Wikipedia-Artikel, die diese Frage perfekt beantworten:",
        "question": "„Welche unterschiedlichen Bräuche, Symbole und Traditionen prägen das Weihnachtsfest in Deutschland, und welche regionalen Unterschiede gibt es dabei?“",
        "expander_label": "📜 Anleitung für Wissens-Trainer (Hier klicken)",
        "instructions": """
        ### 1. Deine Mission
        Deine Aufgabe ist es, **Quellen auszuwählen**, die dem Elf helfen, eine **vollständige** und **richtige** Antwort zu geben.
        
        ### 2. Werkzeugkiste: Suchstrategien
        Der Elf akzeptiert nur **Wikipedia-Links**. Nutze Google clever:
        * `site:de.wikipedia.org Weihnachten`
        * `"Weihnachtsbräuche in Norddeutschland"`
        
        ### 3. So bewertet der Elf dein Training
        * 🧠 **Relevanz:** Passt der Artikel zum Thema?
        * 📚 **Vollständigkeit:** Sind alle wichtigen Begriffe enthalten?
        * 🌍 **Regionale Abdeckung:** Sind Nord, Süd, Ost und West abgedeckt?
        """,
        "input_header": "🔗 Füttere den Elf mit Wissen",
        "num_input_label": "Wie viele Artikel hast du gefunden? (1-8)",
        "link_caption": "Füge hier deine Wikipedia-Links ein:",
        "submit_btn": "🚀 Training starten & Auswerten",
        "spinner": "Der Elf liest deine Artikel... 📖",
        "res_title": "📊 Trainings-Ergebnis",
        "metric_rel": "🧠 Relevanz",
        "metric_comp": "📚 Vollständigkeit",
        "metric_reg": "🌍 Regional",
        "err_link": "⚠️ Hoppla! Der Elf konnte die Links nicht lesen. Sind es echte Wikipedia-Links?",
        "fb_rel_good": "✅ **Super Fokus:** Die Artikel passen perfekt zum Thema.",
        "fb_rel_med": "⚠️ **Geht so:** Die Artikel passen grob, aber es ist viel unwichtiges Zeug dabei.",
        "fb_rel_bad": "❌ **Thema verfehlt:** Der Elf ist verwirrt. Die Artikel handeln kaum von Weihnachten.",
        "fb_comp_good": "✅ **Weihnachts-Profi:** Du hast fast alle wichtigen Traditionen abgedeckt!",
        "fb_comp_med": "⚠️ **Lückenhaft:** Einige Klassiker fehlen.",
        "fb_comp_bad": "❌ **Anfänger-Wissen:** Da fehlen sehr viele Grundlagen.",
        "fb_reg_good": "✅ **Deutschlandreise:** Von den Alpen bis zur See ist alles dabei!",
        "fb_reg_med": "⚠️ **Lokalpatriot:** Du hast manche Regionen gut abgedeckt, aber andere fehlen.",
        "fb_reg_bad": "❌ **Zu allgemein:** Der Elf kennt keine regionalen Unterschiede.",
        "final_success": "🎉 HERVORRAGEND! Der Elf ist bereit für seinen Einsatz! Die Auswahl der Artikel ist sehr gut!"
    },
    "English": {
        "page_title": "Christmas Elf Trainer",
        "main_title": "🎄 Christmas Traditions: Context Evaluation for AI",
        "task_header": "🎅 Mission: Train the Christmas Elf",
        "task_desc_1": "We are building an AI agent to answer tourist questions about Christmas in Germany. But: <strong>The Elf only knows what YOU give him to read!</strong>",
        "task_desc_2": "Find Wikipedia articles that answer this question perfectly:",
        "question": "“What distinct customs, symbols, and traditions define Christmas in Germany, and what regional differences exist?”",
        "expander_label": "📜 Instructions for Knowledge Trainers (Click here)",
        "instructions": """
        ### ⚠️ IMPORTANT: LANGUAGE RULE
        The Elf is training for **Germany**. Even though this interface is in English, **you must find GERMAN Wikipedia articles** (`de.wikipedia.org`). 
        * Do not use English Wikipedia links!
        * Search for terms like *Weihnachten*, *Erzgebirge*, *Adventskranz*.

        ### 1. Your Mission
        Select sources that help the Elf give a **complete** and **correct** answer about German traditions.
        
        ### 2. Toolbox: Search Strategies
        The Elf only accepts **Wikipedia links**. Use Google smartly:
        * `site:de.wikipedia.org Weihnachten`
        * `"Weihnachtsbräuche in Norddeutschland"`
        
        ### 3. How the Elf Grades You
        * 🧠 **Relevance:** Does the article actually talk about German Christmas?
        * 📚 **Completeness:** Did you catch the key terms (Nikolaus, Advent, etc.)?
        * 🌍 **Regional Coverage:** Did you cover North, South, East, and West?
        """,
        "input_header": "🔗 Feed the Elf with Knowledge",
        "num_input_label": "How many articles did you find? (1-8)",
        "link_caption": "Paste your German Wikipedia links here:",
        "submit_btn": "🚀 Start Training & Evaluate",
        "spinner": "The Elf is reading your articles... 📖",
        "res_title": "📊 Training Results",
        "metric_rel": "🧠 Relevance",
        "metric_comp": "📚 Completeness",
        "metric_reg": "🌍 Regional",
        "err_link": "⚠️ Oops! The Elf couldn't read the links. Are they valid Wikipedia URLs?",
        "fb_rel_good": "✅ **Great Focus:** The articles fit the topic perfectly.",
        "fb_rel_med": "⚠️ **Okay:** The articles fit roughly, but there is a lot of unrelated noise.",
        "fb_rel_bad": "❌ **Off Topic:** The Elf is confused. These articles are hardly about Christmas.",
        "fb_comp_good": "✅ **Christmas Pro:** You covered almost all important traditions!",
        "fb_comp_med": "⚠️ **Incomplete:** Some classics are missing.",
        "fb_comp_bad": "❌ **Beginner Knowledge:** Many basics are missing.",
        "fb_reg_good": "✅ **Germany Tour:** From the Alps to the Sea, everything is covered!",
        "fb_reg_med": "⚠️ **Local Patriot:** You covered some regions well, but others are missing.",
        "fb_reg_bad": "❌ **Too General:** The Elf knows no regional differences.",
        "final_success": "🎉 OUTSTANDING! The Elf is ready for duty! Your selection of articles is excellent!"
    }
}

# --- STREAMLIT UI ---
st.set_page_config(page_title="Elf Trainer", page_icon="🎅")

# Language Selector (Top Rightish)
lang = st.radio("Sprache / Language", ["Deutsch", "English"], horizontal=True)
t = TEXTS[lang]

st.title(t["main_title"])

st.markdown(f"""
    <div style="background-color: #262730; padding: 20px; border-radius: 10px; border: 1px solid #4B4B4B; margin-bottom: 20px;">
    <h3>{t['task_header']}</h3>
    <p>{t['task_desc_1']}</p>
    <p>{t['task_desc_2']}</p>
    <blockquote style="background-color: #3e3e3e; color: white;"><em>{t['question']}</em></blockquote>
    </div>
    """, unsafe_allow_html=True)

with st.expander(t["expander_label"], expanded=True):
    st.markdown(t["instructions"])

st.write("---")
st.subheader(t["input_header"])

# Input OUTSIDE form
num_links = st.number_input(t["num_input_label"], min_value=1, max_value=8, value=1)

with st.form("training_form"):
    urls = []
    st.caption(t["link_caption"])
    
    for i in range(num_links):
        urls.append(st.text_input(f"Link {i + 1}", placeholder="https://de.wikipedia.org/wiki/..."))
    
    submitted = st.form_submit_button(t["submit_btn"])

if submitted:
    student_texts = []
    
    with st.spinner(t["spinner"]):
        for url in urls:
            if url.strip():
                content = fetch_wikipedia_content(url)
                if content:
                    student_texts.append(content)
        
        if len(student_texts) >= 1:
            scores = evaluate_contexts(student_texts)
            
            st.write("---")
            st.subheader(t["res_title"])
            
            col1, col2, col3 = st.columns(3)
            col1.metric(t["metric_rel"], f"{scores['relevance']:.2f}", help="> 0.7 is good")
            col2.metric(t["metric_comp"], f"{int(scores['completeness']*100)}%", help="Keywords found")
            col3.metric(t["metric_reg"], f"{int(scores['regional_completeness']*100)}%", help="Regions covered")

            feedback = []
            
            # Relevance Feedback
            if scores["relevance"] > 0.8:
                feedback.append(t["fb_rel_good"])
            elif scores["relevance"] > 0.5:
                feedback.append(t["fb_rel_med"])
            else:
                feedback.append(t["fb_rel_bad"])

            # Completeness Feedback
            if scores["completeness"] > 0.8:
                feedback.append(t["fb_comp_good"])
            elif scores["completeness"] > 0.5:
                feedback.append(t["fb_comp_med"])
            else:
                feedback.append(t["fb_comp_bad"])

            # Regional Feedback
            if scores["regional_completeness"] > 0.8:
                feedback.append(t["fb_reg_good"])
            elif scores["regional_completeness"] > 0.5:
                feedback.append(t["fb_reg_med"])
            else:
                feedback.append(t["fb_reg_bad"])

            st.info("\n\n".join(feedback))

            if scores["relevance"] > 0.8 and scores["completeness"] > 0.9 and scores["regional_completeness"] > 0.8:
                st.balloons()
                st.success(t["final_success"])
        else:
            st.error(t["err_link"])