Lumosdev commited on
Commit
2ef45b1
·
verified ·
1 Parent(s): d2c6ed6

Upload 10 files

Browse files
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,13 @@
1
- ---
2
- title: 34achatbot
3
- emoji: 💬
4
- colorFrom: yellow
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.0.1
8
- app_file: app.py
9
- pinned: false
10
- short_description: Virtueller Dozent zur Vorbereitung auf 34a Sachkundeprüfung
11
- ---
12
-
13
  An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
1
+ ---
2
+ title: 34achatbot
3
+ emoji: 💬
4
+ colorFrom: yellow
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 5.0.1
8
+ app_file: app.py
9
+ pinned: false
10
+ short_description: Virtueller Dozent zur Vorbereitung auf 34a Sachkundeprüfung
11
+ ---
12
+
13
  An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
app.py CHANGED
@@ -1,22 +1,23 @@
1
- import gradio as gr
2
- from utils import lade_skript, teile_in_abschnitte, finde_passenden_abschnitt
3
-
4
- # Lade und teile das Sachkunde-Skript
5
- text = lade_skript()
6
- abschnitte = teile_in_abschnitte(text)
7
-
8
- # Hauptfunktion für den Chatverlauf
9
- def antwortverlauf(chatverlauf):
10
- frage = chatverlauf[-1]["content"]
11
- antwort = finde_passenden_abschnitt(frage, abschnitte)
12
- return chatverlauf + [{"role": "assistant", "content": antwort}]
13
-
14
- # UI mit Gradio ChatInterface
15
- demo = gr.ChatInterface(
16
- fn=antwortverlauf,
17
- title="§34a Lern-Dozent",
18
- description="Frag mich zur Sachkundeprüfung – ich finde die Antwort in deinem IHK-Skript!"
19
- )
20
-
21
- # App starten
22
- demo.launch()
 
 
1
+ import gradio as gr
2
+ from karteikasten import lade_karteikarten, naechste_karte, verarbeite_antwort
3
+
4
+ karten = lade_karteikarten()
5
+ aktuelle_karte = naechste_karte(karten)
6
+
7
+ def quiz(antwort_index):
8
+ global aktuelle_karte, karten
9
+ korrekt, neue_stufe = verarbeite_antwort(aktuelle_karte, antwort_index, karten)
10
+ text = "✅ Richtig!" if korrekt else "❌ Leider falsch."
11
+ feedback = f"{text} Diese Karte ist jetzt in Stufe {neue_stufe}."
12
+ aktuelle_karte = naechste_karte(karten)
13
+ return feedback, aktuelle_karte["frage"], aktuelle_karte["antworten"]
14
+
15
+ with gr.Blocks() as demo:
16
+ frage = gr.Textbox(label="Frage", value=aktuelle_karte["frage"], interactive=False)
17
+ feedback = gr.Textbox(label="Feedback", interactive=False)
18
+ btns = gr.Radio(aktuelle_karte["antworten"], label="Antwort wählen")
19
+ weiter = gr.Button("Antwort prüfen")
20
+
21
+ weiter.click(fn=quiz, inputs=btns, outputs=[feedback, frage, btns])
22
+
23
+ demo.launch()
app_karteikasten.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from karteikasten import lade_karteikarten, naechste_karte, verarbeite_antwort
3
+
4
+ karten = lade_karteikarten()
5
+ aktuelle_karte = naechste_karte(karten)
6
+
7
+ def quiz(antwort_index):
8
+ global aktuelle_karte, karten
9
+ if aktuelle_karte is None:
10
+ return "Alle Karten gelernt!", "", []
11
+ korrekt, neue_stufe = verarbeite_antwort(aktuelle_karte, antwort_index, karten)
12
+ text = "✅ Richtig!" if korrekt else "❌ Leider falsch."
13
+ feedback = f"{text} Diese Karte ist jetzt in Stufe {neue_stufe}."
14
+ aktuelle_karte = naechste_karte(karten)
15
+ if aktuelle_karte:
16
+ return feedback, aktuelle_karte["frage"], aktuelle_karte["antworten"]
17
+ else:
18
+ return "Du hast alle Karten durch!", "", []
19
+
20
+ with gr.Blocks() as demo:
21
+ frage = gr.Textbox(label="Frage", value=aktuelle_karte["frage"] if aktuelle_karte else "", interactive=False)
22
+ feedback = gr.Textbox(label="Feedback", interactive=False)
23
+ btns = gr.Radio(aktuelle_karte["antworten"] if aktuelle_karte else [], label="Antwort wählen")
24
+ weiter = gr.Button("Antwort prüfen")
25
+
26
+ weiter.click(fn=quiz, inputs=btns, outputs=[feedback, frage, btns])
27
+
28
+ demo.launch()
app_karteikasten_fortschritt.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+ import json
4
+ import random
5
+ import matplotlib.pyplot as plt
6
+
7
+ # ---- Karteikasten-Logik (Leitner-System) ----
8
+ DATEI = "karteikarten.json"
9
+
10
+ def lade_karteikarten():
11
+ with open(DATEI, "r", encoding="utf-8") as f:
12
+ return json.load(f)
13
+
14
+ def speichere_karteikarten(karten):
15
+ with open(DATEI, "w", encoding="utf-8") as f:
16
+ json.dump(karten, f, indent=2, ensure_ascii=False)
17
+
18
+ def naechste_karte(karten):
19
+ gewichtet = []
20
+ for karte in karten:
21
+ gewicht = 6 - karte["stufe"]
22
+ gewichtet += [karte] * gewicht
23
+ return random.choice(gewichtet) if gewichtet else None
24
+
25
+ def verarbeite_antwort(karte, antwort_index, alle_karten):
26
+ korrekt = (antwort_index == karte["richtig"])
27
+ if korrekt:
28
+ karte["stufe"] = min(karte["stufe"] + 1, 5)
29
+ else:
30
+ karte["stufe"] = 1
31
+ speichere_karteikarten(alle_karten)
32
+ return korrekt, karte["stufe"]
33
+
34
+ def erstelle_fortschrittsgrafik(karten):
35
+ stufen = [1, 2, 3, 4, 5]
36
+ anzahl_karten = [sum(1 for k in karten if k["stufe"] == s) for s in stufen]
37
+
38
+ plt.figure(figsize=(8, 5))
39
+ plt.bar(stufen, anzahl_karten)
40
+ plt.xlabel("Lernstufe")
41
+ plt.ylabel("Anzahl Karteikarten")
42
+ plt.title("Karteikarten-Fortschritt")
43
+ plt.xticks(stufen)
44
+ plt.grid(axis="y")
45
+ pfad = "karteikasten_fortschritt.png"
46
+ plt.savefig(pfad)
47
+ plt.close()
48
+ return pfad
49
+
50
+ # ---- Gradio-App ----
51
+ karten = lade_karteikarten()
52
+ aktuelle_karte = naechste_karte(karten)
53
+
54
+ def quiz(antwort_index):
55
+ global aktuelle_karte, karten
56
+ if aktuelle_karte is None:
57
+ return "Alle Karten gelernt!", "", []
58
+ korrekt, neue_stufe = verarbeite_antwort(aktuelle_karte, antwort_index, karten)
59
+ text = "✅ Richtig!" if korrekt else "❌ Leider falsch."
60
+ feedback = f"{text} Diese Karte ist jetzt in Stufe {neue_stufe}."
61
+ aktuelle_karte = naechste_karte(karten)
62
+ if aktuelle_karte:
63
+ return feedback, aktuelle_karte["frage"], aktuelle_karte["antworten"]
64
+ else:
65
+ return "Du hast alle Karten durch!", "", []
66
+
67
+ def zeige_fortschritt():
68
+ pfad = erstelle_fortschrittsgrafik(karten)
69
+ return pfad
70
+
71
+ with gr.Blocks() as demo:
72
+ gr.Markdown("# 📚 Karteikarten-Lernen – §34a Leitner-System")
73
+
74
+ frage = gr.Textbox(label="Frage", value=aktuelle_karte["frage"] if aktuelle_karte else "", interactive=False)
75
+ feedback = gr.Textbox(label="Feedback", interactive=False)
76
+ btns = gr.Radio(aktuelle_karte["antworten"] if aktuelle_karte else [], label="Antwort wählen")
77
+ weiter = gr.Button("Antwort prüfen")
78
+
79
+ weiter.click(fn=quiz, inputs=btns, outputs=[feedback, frage, btns])
80
+
81
+ gr.Markdown("## 📊 Fortschritt")
82
+ zeige_btn = gr.Button("Fortschritt anzeigen")
83
+ fortschritt_img = gr.Image()
84
+
85
+ zeige_btn.click(fn=zeige_fortschritt, inputs=None, outputs=fortschritt_img)
86
+
87
+ demo.launch()
karteikarten.json ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "frage": "Was regelt §34a GewO tatsächlich?",
4
+ "antworten": [
5
+ "Die Waffenverwendung bei privaten Sicherheitsdiensten",
6
+ "Die Sachkundeprüfung für das Bewachungsgewerbe",
7
+ "Die Arbeitszeiten von Polizisten"
8
+ ],
9
+ "richtig": 1,
10
+ "stufe": 1
11
+ },
12
+ {
13
+ "frage": "Notwehr darf man nur dann anwenden, wenn...",
14
+ "antworten": [
15
+ "man körperlich überlegen ist.",
16
+ "kein anderer aus der Gruppe eingreifen möchte.",
17
+ "ein gegenwärtiger, rechtswidriger Angriff vorliegt."
18
+ ],
19
+ "richtig": 2,
20
+ "stufe": 1
21
+ },
22
+ {
23
+ "frage": "Was ist KEINE gesetzliche Rechtsquelle?",
24
+ "antworten": [
25
+ "Ein Tweet des Bundeskanzlers",
26
+ "Das Strafgesetzbuch",
27
+ "Das Grundgesetz"
28
+ ],
29
+ "richtig": 0,
30
+ "stufe": 1
31
+ },
32
+ {
33
+ "frage": "Was gehört zu den hoheitlichen Aufgaben, die ein Sicherheitsmitarbeiter NICHT übernehmen darf?",
34
+ "antworten": [
35
+ "Einfache Identitätskontrolle auf dem Gelände",
36
+ "Festnahme mit anschließendem Strafprozess",
37
+ "Hausverbot aussprechen im Auftrag des Besitzers"
38
+ ],
39
+ "richtig": 1,
40
+ "stufe": 1
41
+ },
42
+ {
43
+ "frage": "Welche Aussage über das Grundgesetz ist korrekt?",
44
+ "antworten": [
45
+ "Es gilt nur für staatliche Behörden.",
46
+ "Es ist für Sicherheitsmitarbeiter irrelevant.",
47
+ "Es ist die wichtigste Rechtsquelle in Deutschland."
48
+ ],
49
+ "richtig": 2,
50
+ "stufe": 1
51
+ },
52
+ {
53
+ "frage": "Ein Sicherheitsmitarbeiter darf eine Person durchsuchen, wenn...",
54
+ "antworten": [
55
+ "sie es ausdrücklich erlaubt.",
56
+ "der Mitarbeiter das für sinnvoll hält.",
57
+ "die Person verdächtig aussieht."
58
+ ],
59
+ "richtig": 0,
60
+ "stufe": 1
61
+ },
62
+ {
63
+ "frage": "Was ist ein Beispiel für privates Recht?",
64
+ "antworten": [
65
+ "Hausrecht durch Eigentümer",
66
+ "Polizeigesetz",
67
+ "Straßenverkehrsordnung"
68
+ ],
69
+ "richtig": 0,
70
+ "stufe": 1
71
+ },
72
+ {
73
+ "frage": "Darf ein Sicherheitsmitarbeiter jemanden festnehmen?",
74
+ "antworten": [
75
+ "Nein, das ist ausschließlich Aufgabe der Polizei.",
76
+ "Nur bei einem begründeten Verdacht einer Straftat (§127 StPO).",
77
+ "Immer, wenn jemand sich verdächtig verhält."
78
+ ],
79
+ "richtig": 1,
80
+ "stufe": 1
81
+ },
82
+ {
83
+ "frage": "Welches Recht ergibt sich NICHT aus dem Hausrecht?",
84
+ "antworten": [
85
+ "Das Verhängen einer Geldstrafe",
86
+ "Das Aussprechen eines Hausverbots",
87
+ "Das Festlegen von Zutrittsregeln"
88
+ ],
89
+ "richtig": 0,
90
+ "stufe": 1
91
+ },
92
+ {
93
+ "frage": "Welche Aussage zur Rechtswidrigkeit bei Notwehr ist korrekt?",
94
+ "antworten": [
95
+ "Ein Angriff ist nur rechtswidrig, wenn der Angreifer bewaffnet ist.",
96
+ "Ein Angriff ist rechtswidrig, wenn kein Rechtfertigungsgrund vorliegt.",
97
+ "Ein Angriff ist nie rechtswidrig, wenn er provoziert wurde."
98
+ ],
99
+ "richtig": 1,
100
+ "stufe": 1
101
+ },
102
+ {
103
+ "frage": "Was regelt §34a GewO tatsächlich? (Variante 1)",
104
+ "antworten": [
105
+ "Die Waffenverwendung bei privaten Sicherheitsdiensten",
106
+ "Die Sachkundeprüfung für das Bewachungsgewerbe",
107
+ "Die Arbeitszeiten von Polizisten"
108
+ ],
109
+ "richtig": 1,
110
+ "stufe": 1
111
+ },
112
+ {
113
+ "frage": "Notwehr darf man nur dann anwenden, wenn... (Variante 1)",
114
+ "antworten": [
115
+ "man körperlich überlegen ist.",
116
+ "kein anderer aus der Gruppe eingreifen möchte.",
117
+ "ein gegenwärtiger, rechtswidriger Angriff vorliegt."
118
+ ],
119
+ "richtig": 2,
120
+ "stufe": 1
121
+ },
122
+ {
123
+ "frage": "Was ist KEINE gesetzliche Rechtsquelle? (Variante 1)",
124
+ "antworten": [
125
+ "Ein Tweet des Bundeskanzlers",
126
+ "Das Strafgesetzbuch",
127
+ "Das Grundgesetz"
128
+ ],
129
+ "richtig": 0,
130
+ "stufe": 1
131
+ },
132
+ {
133
+ "frage": "Was gehört zu den hoheitlichen Aufgaben, die ein Sicherheitsmitarbeiter NICHT übernehmen darf? (Variante 1)",
134
+ "antworten": [
135
+ "Einfache Identitätskontrolle auf dem Gelände",
136
+ "Festnahme mit anschließendem Strafprozess",
137
+ "Hausverbot aussprechen im Auftrag des Besitzers"
138
+ ],
139
+ "richtig": 1,
140
+ "stufe": 1
141
+ },
142
+ {
143
+ "frage": "Welche Aussage über das Grundgesetz ist korrekt? (Variante 1)",
144
+ "antworten": [
145
+ "Es gilt nur für staatliche Behörden.",
146
+ "Es ist für Sicherheitsmitarbeiter irrelevant.",
147
+ "Es ist die wichtigste Rechtsquelle in Deutschland."
148
+ ],
149
+ "richtig": 2,
150
+ "stufe": 1
151
+ },
152
+ {
153
+ "frage": "Ein Sicherheitsmitarbeiter darf eine Person durchsuchen, wenn... (Variante 1)",
154
+ "antworten": [
155
+ "sie es ausdrücklich erlaubt.",
156
+ "der Mitarbeiter das für sinnvoll hält.",
157
+ "die Person verdächtig aussieht."
158
+ ],
159
+ "richtig": 0,
160
+ "stufe": 1
161
+ },
162
+ {
163
+ "frage": "Was ist ein Beispiel für privates Recht? (Variante 1)",
164
+ "antworten": [
165
+ "Hausrecht durch Eigentümer",
166
+ "Polizeigesetz",
167
+ "Straßenverkehrsordnung"
168
+ ],
169
+ "richtig": 0,
170
+ "stufe": 1
171
+ },
172
+ {
173
+ "frage": "Darf ein Sicherheitsmitarbeiter jemanden festnehmen? (Variante 1)",
174
+ "antworten": [
175
+ "Nein, das ist ausschließlich Aufgabe der Polizei.",
176
+ "Nur bei einem begründeten Verdacht einer Straftat (§127 StPO).",
177
+ "Immer, wenn jemand sich verdächtig verhält."
178
+ ],
179
+ "richtig": 1,
180
+ "stufe": 1
181
+ },
182
+ {
183
+ "frage": "Welches Recht ergibt sich NICHT aus dem Hausrecht? (Variante 1)",
184
+ "antworten": [
185
+ "Das Verhängen einer Geldstrafe",
186
+ "Das Aussprechen eines Hausverbots",
187
+ "Das Festlegen von Zutrittsregeln"
188
+ ],
189
+ "richtig": 0,
190
+ "stufe": 1
191
+ },
192
+ {
193
+ "frage": "Welche Aussage zur Rechtswidrigkeit bei Notwehr ist korrekt? (Variante 1)",
194
+ "antworten": [
195
+ "Ein Angriff ist nur rechtswidrig, wenn der Angreifer bewaffnet ist.",
196
+ "Ein Angriff ist rechtswidrig, wenn kein Rechtfertigungsgrund vorliegt.",
197
+ "Ein Angriff ist nie rechtswidrig, wenn er provoziert wurde."
198
+ ],
199
+ "richtig": 1,
200
+ "stufe": 1
201
+ },
202
+ {
203
+ "frage": "Was regelt §34a GewO tatsächlich? (Variante 2)",
204
+ "antworten": [
205
+ "Die Waffenverwendung bei privaten Sicherheitsdiensten",
206
+ "Die Sachkundeprüfung für das Bewachungsgewerbe",
207
+ "Die Arbeitszeiten von Polizisten"
208
+ ],
209
+ "richtig": 1,
210
+ "stufe": 1
211
+ },
212
+ {
213
+ "frage": "Notwehr darf man nur dann anwenden, wenn... (Variante 2)",
214
+ "antworten": [
215
+ "man körperlich überlegen ist.",
216
+ "kein anderer aus der Gruppe eingreifen möchte.",
217
+ "ein gegenwärtiger, rechtswidriger Angriff vorliegt."
218
+ ],
219
+ "richtig": 2,
220
+ "stufe": 1
221
+ },
222
+ {
223
+ "frage": "Was ist KEINE gesetzliche Rechtsquelle? (Variante 2)",
224
+ "antworten": [
225
+ "Ein Tweet des Bundeskanzlers",
226
+ "Das Strafgesetzbuch",
227
+ "Das Grundgesetz"
228
+ ],
229
+ "richtig": 0,
230
+ "stufe": 1
231
+ },
232
+ {
233
+ "frage": "Was gehört zu den hoheitlichen Aufgaben, die ein Sicherheitsmitarbeiter NICHT übernehmen darf? (Variante 2)",
234
+ "antworten": [
235
+ "Einfache Identitätskontrolle auf dem Gelände",
236
+ "Festnahme mit anschließendem Strafprozess",
237
+ "Hausverbot aussprechen im Auftrag des Besitzers"
238
+ ],
239
+ "richtig": 1,
240
+ "stufe": 1
241
+ },
242
+ {
243
+ "frage": "Welche Aussage über das Grundgesetz ist korrekt? (Variante 2)",
244
+ "antworten": [
245
+ "Es gilt nur für staatliche Behörden.",
246
+ "Es ist für Sicherheitsmitarbeiter irrelevant.",
247
+ "Es ist die wichtigste Rechtsquelle in Deutschland."
248
+ ],
249
+ "richtig": 2,
250
+ "stufe": 1
251
+ },
252
+ {
253
+ "frage": "Ein Sicherheitsmitarbeiter darf eine Person durchsuchen, wenn... (Variante 2)",
254
+ "antworten": [
255
+ "sie es ausdrücklich erlaubt.",
256
+ "der Mitarbeiter das für sinnvoll hält.",
257
+ "die Person verdächtig aussieht."
258
+ ],
259
+ "richtig": 0,
260
+ "stufe": 1
261
+ },
262
+ {
263
+ "frage": "Was ist ein Beispiel für privates Recht? (Variante 2)",
264
+ "antworten": [
265
+ "Hausrecht durch Eigentümer",
266
+ "Polizeigesetz",
267
+ "Straßenverkehrsordnung"
268
+ ],
269
+ "richtig": 0,
270
+ "stufe": 1
271
+ },
272
+ {
273
+ "frage": "Darf ein Sicherheitsmitarbeiter jemanden festnehmen? (Variante 2)",
274
+ "antworten": [
275
+ "Nein, das ist ausschließlich Aufgabe der Polizei.",
276
+ "Nur bei einem begründeten Verdacht einer Straftat (§127 StPO).",
277
+ "Immer, wenn jemand sich verdächtig verhält."
278
+ ],
279
+ "richtig": 1,
280
+ "stufe": 1
281
+ },
282
+ {
283
+ "frage": "Welches Recht ergibt sich NICHT aus dem Hausrecht? (Variante 2)",
284
+ "antworten": [
285
+ "Das Verhängen einer Geldstrafe",
286
+ "Das Aussprechen eines Hausverbots",
287
+ "Das Festlegen von Zutrittsregeln"
288
+ ],
289
+ "richtig": 0,
290
+ "stufe": 1
291
+ },
292
+ {
293
+ "frage": "Welche Aussage zur Rechtswidrigkeit bei Notwehr ist korrekt? (Variante 2)",
294
+ "antworten": [
295
+ "Ein Angriff ist nur rechtswidrig, wenn der Angreifer bewaffnet ist.",
296
+ "Ein Angriff ist rechtswidrig, wenn kein Rechtfertigungsgrund vorliegt.",
297
+ "Ein Angriff ist nie rechtswidrig, wenn er provoziert wurde."
298
+ ],
299
+ "richtig": 1,
300
+ "stufe": 1
301
+ },
302
+ {
303
+ "frage": "Was regelt §34a GewO tatsächlich? (Variante 3)",
304
+ "antworten": [
305
+ "Die Waffenverwendung bei privaten Sicherheitsdiensten",
306
+ "Die Sachkundeprüfung für das Bewachungsgewerbe",
307
+ "Die Arbeitszeiten von Polizisten"
308
+ ],
309
+ "richtig": 1,
310
+ "stufe": 1
311
+ },
312
+ {
313
+ "frage": "Notwehr darf man nur dann anwenden, wenn... (Variante 3)",
314
+ "antworten": [
315
+ "man körperlich überlegen ist.",
316
+ "kein anderer aus der Gruppe eingreifen möchte.",
317
+ "ein gegenwärtiger, rechtswidriger Angriff vorliegt."
318
+ ],
319
+ "richtig": 2,
320
+ "stufe": 1
321
+ },
322
+ {
323
+ "frage": "Was ist KEINE gesetzliche Rechtsquelle? (Variante 3)",
324
+ "antworten": [
325
+ "Ein Tweet des Bundeskanzlers",
326
+ "Das Strafgesetzbuch",
327
+ "Das Grundgesetz"
328
+ ],
329
+ "richtig": 0,
330
+ "stufe": 1
331
+ },
332
+ {
333
+ "frage": "Was gehört zu den hoheitlichen Aufgaben, die ein Sicherheitsmitarbeiter NICHT übernehmen darf? (Variante 3)",
334
+ "antworten": [
335
+ "Einfache Identitätskontrolle auf dem Gelände",
336
+ "Festnahme mit anschließendem Strafprozess",
337
+ "Hausverbot aussprechen im Auftrag des Besitzers"
338
+ ],
339
+ "richtig": 1,
340
+ "stufe": 1
341
+ },
342
+ {
343
+ "frage": "Welche Aussage über das Grundgesetz ist korrekt? (Variante 3)",
344
+ "antworten": [
345
+ "Es gilt nur für staatliche Behörden.",
346
+ "Es ist für Sicherheitsmitarbeiter irrelevant.",
347
+ "Es ist die wichtigste Rechtsquelle in Deutschland."
348
+ ],
349
+ "richtig": 2,
350
+ "stufe": 1
351
+ },
352
+ {
353
+ "frage": "Ein Sicherheitsmitarbeiter darf eine Person durchsuchen, wenn... (Variante 3)",
354
+ "antworten": [
355
+ "sie es ausdrücklich erlaubt.",
356
+ "der Mitarbeiter das für sinnvoll hält.",
357
+ "die Person verdächtig aussieht."
358
+ ],
359
+ "richtig": 0,
360
+ "stufe": 1
361
+ },
362
+ {
363
+ "frage": "Was ist ein Beispiel für privates Recht? (Variante 3)",
364
+ "antworten": [
365
+ "Hausrecht durch Eigentümer",
366
+ "Polizeigesetz",
367
+ "Straßenverkehrsordnung"
368
+ ],
369
+ "richtig": 0,
370
+ "stufe": 1
371
+ },
372
+ {
373
+ "frage": "Darf ein Sicherheitsmitarbeiter jemanden festnehmen? (Variante 3)",
374
+ "antworten": [
375
+ "Nein, das ist ausschließlich Aufgabe der Polizei.",
376
+ "Nur bei einem begründeten Verdacht einer Straftat (§127 StPO).",
377
+ "Immer, wenn jemand sich verdächtig verhält."
378
+ ],
379
+ "richtig": 1,
380
+ "stufe": 1
381
+ },
382
+ {
383
+ "frage": "Welches Recht ergibt sich NICHT aus dem Hausrecht? (Variante 3)",
384
+ "antworten": [
385
+ "Das Verhängen einer Geldstrafe",
386
+ "Das Aussprechen eines Hausverbots",
387
+ "Das Festlegen von Zutrittsregeln"
388
+ ],
389
+ "richtig": 0,
390
+ "stufe": 1
391
+ },
392
+ {
393
+ "frage": "Welche Aussage zur Rechtswidrigkeit bei Notwehr ist korrekt? (Variante 3)",
394
+ "antworten": [
395
+ "Ein Angriff ist nur rechtswidrig, wenn der Angreifer bewaffnet ist.",
396
+ "Ein Angriff ist rechtswidrig, wenn kein Rechtfertigungsgrund vorliegt.",
397
+ "Ein Angriff ist nie rechtswidrig, wenn er provoziert wurde."
398
+ ],
399
+ "richtig": 1,
400
+ "stufe": 1
401
+ },
402
+ {
403
+ "frage": "Was regelt §34a GewO tatsächlich? (Variante 4)",
404
+ "antworten": [
405
+ "Die Waffenverwendung bei privaten Sicherheitsdiensten",
406
+ "Die Sachkundeprüfung für das Bewachungsgewerbe",
407
+ "Die Arbeitszeiten von Polizisten"
408
+ ],
409
+ "richtig": 1,
410
+ "stufe": 1
411
+ },
412
+ {
413
+ "frage": "Notwehr darf man nur dann anwenden, wenn... (Variante 4)",
414
+ "antworten": [
415
+ "man körperlich überlegen ist.",
416
+ "kein anderer aus der Gruppe eingreifen möchte.",
417
+ "ein gegenwärtiger, rechtswidriger Angriff vorliegt."
418
+ ],
419
+ "richtig": 2,
420
+ "stufe": 1
421
+ },
422
+ {
423
+ "frage": "Was ist KEINE gesetzliche Rechtsquelle? (Variante 4)",
424
+ "antworten": [
425
+ "Ein Tweet des Bundeskanzlers",
426
+ "Das Strafgesetzbuch",
427
+ "Das Grundgesetz"
428
+ ],
429
+ "richtig": 0,
430
+ "stufe": 1
431
+ },
432
+ {
433
+ "frage": "Was gehört zu den hoheitlichen Aufgaben, die ein Sicherheitsmitarbeiter NICHT übernehmen darf? (Variante 4)",
434
+ "antworten": [
435
+ "Einfache Identitätskontrolle auf dem Gelände",
436
+ "Festnahme mit anschließendem Strafprozess",
437
+ "Hausverbot aussprechen im Auftrag des Besitzers"
438
+ ],
439
+ "richtig": 1,
440
+ "stufe": 1
441
+ },
442
+ {
443
+ "frage": "Welche Aussage über das Grundgesetz ist korrekt? (Variante 4)",
444
+ "antworten": [
445
+ "Es gilt nur für staatliche Behörden.",
446
+ "Es ist für Sicherheitsmitarbeiter irrelevant.",
447
+ "Es ist die wichtigste Rechtsquelle in Deutschland."
448
+ ],
449
+ "richtig": 2,
450
+ "stufe": 1
451
+ },
452
+ {
453
+ "frage": "Ein Sicherheitsmitarbeiter darf eine Person durchsuchen, wenn... (Variante 4)",
454
+ "antworten": [
455
+ "sie es ausdrücklich erlaubt.",
456
+ "der Mitarbeiter das für sinnvoll hält.",
457
+ "die Person verdächtig aussieht."
458
+ ],
459
+ "richtig": 0,
460
+ "stufe": 1
461
+ },
462
+ {
463
+ "frage": "Was ist ein Beispiel für privates Recht? (Variante 4)",
464
+ "antworten": [
465
+ "Hausrecht durch Eigentümer",
466
+ "Polizeigesetz",
467
+ "Straßenverkehrsordnung"
468
+ ],
469
+ "richtig": 0,
470
+ "stufe": 1
471
+ },
472
+ {
473
+ "frage": "Darf ein Sicherheitsmitarbeiter jemanden festnehmen? (Variante 4)",
474
+ "antworten": [
475
+ "Nein, das ist ausschließlich Aufgabe der Polizei.",
476
+ "Nur bei einem begründeten Verdacht einer Straftat (§127 StPO).",
477
+ "Immer, wenn jemand sich verdächtig verhält."
478
+ ],
479
+ "richtig": 1,
480
+ "stufe": 1
481
+ },
482
+ {
483
+ "frage": "Welches Recht ergibt sich NICHT aus dem Hausrecht? (Variante 4)",
484
+ "antworten": [
485
+ "Das Verhängen einer Geldstrafe",
486
+ "Das Aussprechen eines Hausverbots",
487
+ "Das Festlegen von Zutrittsregeln"
488
+ ],
489
+ "richtig": 0,
490
+ "stufe": 1
491
+ },
492
+ {
493
+ "frage": "Welche Aussage zur Rechtswidrigkeit bei Notwehr ist korrekt? (Variante 4)",
494
+ "antworten": [
495
+ "Ein Angriff ist nur rechtswidrig, wenn der Angreifer bewaffnet ist.",
496
+ "Ein Angriff ist rechtswidrig, wenn kein Rechtfertigungsgrund vorliegt.",
497
+ "Ein Angriff ist nie rechtswidrig, wenn er provoziert wurde."
498
+ ],
499
+ "richtig": 1,
500
+ "stufe": 1
501
+ }
502
+ ]
karteikarten.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import random
3
+
4
+ DATEI = "karteikarten.json"
5
+
6
+ def lade_karteikarten():
7
+ with open(DATEI, "r", encoding="utf-8") as f:
8
+ return json.load(f)
9
+
10
+ def speichere_karteikarten(karten):
11
+ with open(DATEI, "w", encoding="utf-8") as f:
12
+ json.dump(karten, f, indent=2, ensure_ascii=False)
13
+
14
+ def naechste_karte(karten):
15
+ gewichtet = []
16
+ for karte in karten:
17
+ gewicht = 6 - karte["stufe"]
18
+ gewichtet += [karte] * gewicht
19
+ return random.choice(gewichted) if gewichtet else None
20
+
21
+ def verarbeite_antwort(karte, antwort_index, alle_karten):
22
+ korrekt = (antwort_index == karte["richtig"])
23
+ if korrekt:
24
+ karte["stufe"] = min(karte["stufe"] + 1, 5)
25
+ else:
26
+ karte["stufe"] = 1
27
+ speichere_karteikarten(alle_karten)
28
+ return korrekt, karte["stufe"]
karteikasten_fortschritt.png ADDED
utils.py CHANGED
@@ -1,16 +1,16 @@
1
- import re
2
-
3
- def lade_skript(datei="data/sachkunde.md"):
4
- with open(datei, "r", encoding="utf-8") as f:
5
- return f.read()
6
-
7
- def teile_in_abschnitte(text, max_länge=500):
8
- roh = re.split(r"\n{2,}", text) # Trenne nach Leerzeilen
9
- return [abschnitt.strip() for abschnitt in roh if len(abschnitt.strip()) > 30]
10
-
11
- def finde_passenden_abschnitt(frage, abschnitte):
12
- frage = frage.lower()
13
- treffer = [a for a in abschnitte if any(w in a.lower() for w in frage.split())]
14
- if treffer:
15
- return max(treffer, key=lambda x: sum(w in x.lower() for w in frage.split()))
16
- return "Ich konnte keine passende Stelle im Skript finden."
 
1
+ import re
2
+
3
+ def lade_skript(datei="data/sachkunde.md"):
4
+ with open(datei, "r", encoding="utf-8") as f:
5
+ return f.read()
6
+
7
+ def teile_in_abschnitte(text, max_länge=500):
8
+ roh = re.split(r"\n{2,}", text) # Trenne nach Leerzeilen
9
+ return [abschnitt.strip() for abschnitt in roh if len(abschnitt.strip()) > 30]
10
+
11
+ def finde_passenden_abschnitt(frage, abschnitte):
12
+ frage = frage.lower()
13
+ treffer = [a for a in abschnitte if any(w in a.lower() for w in frage.split())]
14
+ if treffer:
15
+ return max(treffer, key=lambda x: sum(w in x.lower() for w in frage.split()))
16
+ return "Ich konnte keine passende Stelle im Skript finden."