BlindKnifemaker commited on
Commit
c73b203
·
verified ·
1 Parent(s): 2a9125c

Upload 4 files

Browse files
Files changed (4) hide show
  1. NASAZENI_HUGGINGFACE.md +141 -0
  2. README_HF.md +44 -0
  3. app.py +516 -0
  4. requirements.txt +1 -0
NASAZENI_HUGGINGFACE.md ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Průvodce nasazením testu na Hugging Face
2
+
3
+ ## Krok 1: Příprava účtu
4
+ 1. Jděte na https://huggingface.co
5
+ 2. Pokud nemáte účet, zaregistrujte se (zdarma)
6
+ 3. Přihlaste se
7
+
8
+ ## Krok 2: Vytvoření Space
9
+ 1. Klikněte na váš profil (vpravo nahoře)
10
+ 2. Vyberte **"Spaces"**
11
+ 3. Klikněte **"Create new Space"**
12
+
13
+ ### Nastavení Space:
14
+ - **Owner**: Váš uživatel/organizace
15
+ - **Space name**: `ktf-ai-test` (nebo libovolný název)
16
+ - **License**: MIT nebo Apache 2.0
17
+ - **Select SDK**: **Gradio** ⚠️ DŮLEŽITÉ
18
+ - **Space hardware**: CPU basic - free (dostačující)
19
+ - **Visibility**: Public nebo Private (podle preference)
20
+
21
+ 4. Klikněte **"Create Space"**
22
+
23
+ ## Krok 3: Nahrání souborů
24
+ Po vytvoření Space se zobrazí prázdný prostor.
25
+
26
+ 1. Klikněte na záložku **"Files"** (nebo **"Files and versions"**)
27
+ 2. Klikněte **"Add file"** → **"Upload files"**
28
+ 3. Nahrajte tyto 3 soubory (máte je stažené):
29
+ - `app.py`
30
+ - `requirements.txt`
31
+ - `README_HF.md` (můžete přejmenovat na `README.md`)
32
+
33
+ 4. Do commit message napište: "Initial upload"
34
+ 5. Klikněte **"Commit changes to main"**
35
+
36
+ ## Krok 4: Čekání na build
37
+ - Hugging Face automaticky začne sestavovat aplikaci
38
+ - V záložce **"App"** uvidíte:
39
+ - První řádek: "Building..." (cca 1-2 minuty)
40
+ - Pak: "Running..."
41
+ - Nakonec: **Vaše aplikace se zobrazí!** 🎉
42
+
43
+ ## Krok 5: Testování
44
+
45
+ ### Test aplikace:
46
+ 1. V záložce **"App"** uvidíte běžící test
47
+ 2. Zkusíme to otestovat:
48
+ - **Kód účastníka**: `TEST-001`
49
+ - **Typ testu**: Vyberte STAFF
50
+ - Klikněte **"Začít test"**
51
+ 3. Odpovězte na otázky
52
+ 4. Odešlete test
53
+ 5. Zkontrolujte výsledky
54
+
55
+ ### Stažení výsledků:
56
+ 1. Přejděte na záložku **"Files"**
57
+ 2. Po absolvování testů se zde objeví:
58
+ - `vysledky_testu.csv` - výsledky
59
+ - `zpetna_vazba.csv` - zpětná vazba
60
+ 3. Klikněte na soubor a **"Download"**
61
+
62
+ ## Krok 6: Sdílení s účastníky
63
+
64
+ ### URL vašeho testu:
65
+ ```
66
+ https://huggingface.co/spaces/VAS_USERNAME/ktf-ai-test
67
+ ```
68
+
69
+ Například:
70
+ ```
71
+ https://huggingface.co/spaces/jannovak/ktf-ai-test
72
+ ```
73
+
74
+ ### Generování kódů pro účastníky:
75
+ Doporučený formát: `KTF2025-XXX`
76
+
77
+ Příklady:
78
+ - KTF2025-001
79
+ - KTF2025-002
80
+ - KTF2025-003
81
+ - ...
82
+
83
+ 💡 **TIP**: Vytvořte si Excel tabulku s kódy a jmény účastníků
84
+
85
+ ## Krok 7: Údržba během testování
86
+
87
+ ### Kontrola běhu aplikace:
88
+ - Space běží **7 dní zdarma** na free tieru
89
+ - Poté přejde do "sleep mode"
90
+ - Kliknutím na Space se opět probudí
91
+
92
+ ### Stahování výsledků:
93
+ - **Stahujte CSV pravidelně** (např. každý den)
94
+ - Hugging Face může soubory smazat při restartování
95
+
96
+ ### Prodloužení doby běhu:
97
+ Pokud chcete, aby Space běžel déle:
98
+ 1. Jděte do Settings Space
99
+ 2. Zapněte **"Persistent Storage"** (zpoplatněno ~$5/měsíc)
100
+ 3. Data se pak neztratí při restartování
101
+
102
+ ## Krok 8: Analýza výsledků
103
+
104
+ ### Struktura vysledky_testu.csv:
105
+ ```
106
+ timestamp, kod_ucastnika, typ_testu, skore, maximalni_skore, procenta, odpovedi
107
+ ```
108
+
109
+ ### Struktura zpetna_vazba.csv:
110
+ ```
111
+ timestamp, kod_ucastnika, typ_testu, obtiznost, srozumitelnost, uzitecnost, komentar
112
+ ```
113
+
114
+ Otevřete v Excelu nebo Google Sheets pro analýzu.
115
+
116
+ ## Řešení problémů
117
+
118
+ ### Aplikace se nezobrazuje:
119
+ 1. Zkontrolujte záložku **"Logs"** pro chybové hlášky
120
+ 2. Ujistěte se, že SDK je nastaveno na **Gradio**
121
+ 3. Zkuste restartovat Space (Settings → Restart Space)
122
+
123
+ ### CSV soubory se neukládají:
124
+ 1. Někdo musel absolvovat alespoň jeden test
125
+ 2. Soubory se vytvoří až po prvním odeslání
126
+ 3. Zkontrolujte záložku "Files"
127
+
128
+ ### Space přešel do sleep mode:
129
+ - Jednoduše otevřete URL space znovu
130
+ - Probudí se automaticky (cca 1 minuta)
131
+
132
+ ## Kontakt a podpora
133
+
134
+ Pro technickou podporu:
135
+ - Hugging Face komunita: https://huggingface.co/forum
136
+ - Dokumentace Gradio: https://gradio.app/docs
137
+
138
+ ---
139
+
140
+ **Vytvořeno pro:** Katolická teologická fakulta UK, Praha 2025
141
+ **Verze:** 1.0
README_HF.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Test AI znalostí - KTF UK
2
+
3
+ Gradio aplikace pro testování znalostí generativní AI.
4
+
5
+ ## Nasazení na Hugging Face Spaces
6
+
7
+ 1. Vytvořte nový Space na https://huggingface.co/spaces
8
+ 2. Vyberte SDK: **Gradio**
9
+ 3. Nahrajte tyto soubory:
10
+ - `app.py`
11
+ - `requirements.txt`
12
+ - `README.md`
13
+
14
+ ## Tracking účastníků
15
+
16
+ Aplikace automaticky ukládá:
17
+ - **vysledky_testu.csv** - výsledky všech účastníků
18
+ - **zpetna_vazba.csv** - zpětná vazba
19
+
20
+ Tyto soubory stáhnete z Files záložky vašeho Space.
21
+
22
+ ## Generování kódů účastníků
23
+
24
+ Doporučený formát: `KTF2025-XXX`
25
+
26
+ Příklad:
27
+ - KTF2025-001
28
+ - KTF2025-002
29
+ - atd.
30
+
31
+ ## Minimální požadavky pro úspěch
32
+
33
+ - **STAFF test:** 7/10 bodů
34
+ - **ACADEMIC test:** 8/15 bodů
35
+
36
+ ## Poznámky
37
+
38
+ - Aplikace běží 7 dní zdarma na Free tier
39
+ - Pro delší provoz použijte Persistent Storage
40
+ - Výsledky stahujte pravidelně
41
+
42
+ ## Kontakt
43
+
44
+ Katolická teologická fakulta UK, Praha 2025
app.py ADDED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import csv
4
+ from datetime import datetime
5
+ import os
6
+
7
+ # Data úložiště
8
+ RESULTS_FILE = "vysledky_testu.csv"
9
+ FEEDBACK_FILE = "zpetna_vazba.csv"
10
+
11
+ # Inicializace souborů
12
+ if not os.path.exists(RESULTS_FILE):
13
+ with open(RESULTS_FILE, 'w', newline='', encoding='utf-8') as f:
14
+ writer = csv.writer(f)
15
+ writer.writerow(['timestamp', 'kod_ucastnika', 'typ_testu', 'skore', 'maximalni_skore', 'procenta', 'odpovedi'])
16
+
17
+ if not os.path.exists(FEEDBACK_FILE):
18
+ with open(FEEDBACK_FILE, 'w', newline='', encoding='utf-8') as f:
19
+ writer = csv.writer(f)
20
+ writer.writerow(['timestamp', 'kod_ucastnika', 'typ_testu', 'obtiznost', 'srozumitelnost', 'uzitecnost', 'komentar'])
21
+
22
+ # Definice testů
23
+ TESTS = {
24
+ "STAFF": {
25
+ "nazev": "Test pro administrativní pracovníky (STAFF)",
26
+ "popis": "10 otázek zaměřených na praktické použití AI v kanceláři",
27
+ "otazky": [
28
+ {
29
+ "q": "Jaká je doporučená struktura efektivního promptu pro práci s AI?",
30
+ "opts": [
31
+ "A) Role + Kontext + Úkol + Formát",
32
+ "B) Pouze úkol, ostatní AI domyslí sama",
33
+ "C) Poskytnutí jasné role AI zlepšuje kvalitu odpovědí",
34
+ "D) Formát výstupu není důležitý",
35
+ "E) Kontext pomáhá AI lépe pochopit situaci"
36
+ ],
37
+ "spravne": ["A", "C", "E"]
38
+ },
39
+ {
40
+ "q": "Co přesně znamená termín 'zero-shot prompting'?",
41
+ "opts": [
42
+ "A) Poskytnutí jednoho vzorového příkladu",
43
+ "B) Zadání instrukce bez jakýchkoliv příkladů",
44
+ "C) Poskytnutí tří vzorových příkladů",
45
+ "D) Nejjednodušší forma práce s AI",
46
+ "E) Vždy poskytuje nejlepší výsledky"
47
+ ],
48
+ "spravne": ["B", "D"]
49
+ },
50
+ {
51
+ "q": "Co je 'answer pressure testing' a k čemu slouží?",
52
+ "opts": [
53
+ "A) Technika pro zrychlení generování odpovědí",
54
+ "B) Žádost, aby AI zkontrolovala a zdůvodnila své odpovědi",
55
+ "C) Příklad: 'Jsi si tímto výsledkem jistý? Zkontroluj svoje úvahy.'",
56
+ "D) Pomáhá odhalit případné halucinace AI",
57
+ "E) Snižuje kvalitu odpovědí tím, že AI zmate"
58
+ ],
59
+ "spravne": ["B", "C", "D"]
60
+ },
61
+ {
62
+ "q": "Které z následujících úkolů lze bezpečně řešit pomocí AI v kancelářské práci?",
63
+ "opts": [
64
+ "A) Shrnutí dlouhých dokumentů do kratší formy",
65
+ "B) Extrakce konkrétních informací (jména, data, částky) z dokumentů",
66
+ "C) Anonymizace osobních údajů v dokumentech",
67
+ "D) Fyzická archivace papírových dokumentů",
68
+ "E) Překlad textů a změna stylu komunikace"
69
+ ],
70
+ "spravne": ["A", "B", "C", "E"]
71
+ },
72
+ {
73
+ "q": "Co přesně jsou 'halucinace' v kontextu AI systémů?",
74
+ "opts": [
75
+ "A) AI vymýšlí informace, které vypadají věrohodně, ale jsou nepravdivé",
76
+ "B) Halucinace jsou vždy snadno rozpoznatelné",
77
+ "C) Je nezbytné vždy ověřovat důležitá fakta z jiných zdrojů",
78
+ "D) Answer pressure testing může pomoci odhalit halucinace",
79
+ "E) Nové modely AI už halucinace nemají"
80
+ ],
81
+ "spravne": ["A", "C", "D"]
82
+ },
83
+ {
84
+ "q": "Co je 'token' a proč je tento pojem důležitý?",
85
+ "opts": [
86
+ "A) Token odpovídá přibližně 4 znakům textu",
87
+ "B) Token je základní jednotka zpracování textu v AI",
88
+ "C) Token je měna pro placení AI služeb",
89
+ "D) AI modely mají limit na počet tokenů",
90
+ "E) Token je totéž co jedno slovo"
91
+ ],
92
+ "spravne": ["A", "B", "D"]
93
+ },
94
+ {
95
+ "q": "Jak správně pracovat s AI při respektování GDPR?",
96
+ "opts": [
97
+ "A) Anonymizovat všechny osobní údaje před nahráním do AI",
98
+ "B) GDPR se na práci s AI nevztahuje",
99
+ "C) Nikdy neposílat citlivá data do veřejných AI systémů",
100
+ "D) Znát politiku zpracování dat AI platformy",
101
+ "E) Osobní údaje lze do AI nahrávat bez omezení"
102
+ ],
103
+ "spravne": ["A", "C", "D"]
104
+ },
105
+ {
106
+ "q": "Jak správně pracovat s češtinou vs. angličtinou při použití AI?",
107
+ "opts": [
108
+ "A) Pro češtinu explicitně uvést 'v češtině'",
109
+ "B) AI automaticky rozpozná jazyk vždy správně",
110
+ "C) Pro vědu preferovat angličtinu",
111
+ "D) Kvalita je stejná pro všechny jazyky",
112
+ "E) Lze kombinovat jazyky podle potřeby"
113
+ ],
114
+ "spravne": ["A", "C", "E"]
115
+ },
116
+ {
117
+ "q": "Co znamená 'chain-of-thought prompting' a kdy ho použít?",
118
+ "opts": [
119
+ "A) Žádost o postupné vysvětlení kroků",
120
+ "B) Nejrychlejší způsob generování",
121
+ "C) Užitečné pro komplexní analýzy",
122
+ "D) Příklad: 'Analyzuj: 1) témata 2) problémy 3) řešení'",
123
+ "E) Nevhodné pro analytické úlohy"
124
+ ],
125
+ "spravne": ["A", "C", "D"]
126
+ },
127
+ {
128
+ "q": "Co je 'role-playing' v kontextu práce s AI?",
129
+ "opts": [
130
+ "A) AI přiřadíte konkrétní roli",
131
+ "B) Příklad: 'Jsi zkušený HR manažer s 20 lety praxe'",
132
+ "C) Role nijak neovlivňuje odpovědi",
133
+ "D) Role pomáhá přizpůsobit jazyk a odbornost",
134
+ "E) Používá se pouze pro zábavu"
135
+ ],
136
+ "spravne": ["A", "B", "D"]
137
+ }
138
+ ]
139
+ },
140
+ "ACADEMIC": {
141
+ "nazev": "Test pro akademické pracovníky (ACADEMIC)",
142
+ "popis": "12 otázek: 6 základních + 6 metodologických",
143
+ "otazky": [
144
+ # Základní 1-6
145
+ {
146
+ "q": "Jaká je struktura akademického promptu?",
147
+ "opts": [
148
+ "A) Role + Kontext + Úkol + Formát + Omezení",
149
+ "B) Pouze úkol",
150
+ "C) Požadavek na rozlišení fakta/interpretace",
151
+ "D) Žádost o označení míry jistoty",
152
+ "E) Formát není důležitý"
153
+ ],
154
+ "spravne": ["A", "C", "D"],
155
+ "body": 1
156
+ },
157
+ {
158
+ "q": "Co je 'answer pressure testing' a proč je v akademii kritický?",
159
+ "opts": [
160
+ "A) Technika systematického zpochybňování",
161
+ "B) Příklad: 'Jsi si jistý? Odkud to? Alternativy?'",
162
+ "C) Pomáhá odhalit halucinace",
163
+ "D) V akademii méně důležitý než v kanceláři",
164
+ "E) Nutí AI přiznat nejistotu"
165
+ ],
166
+ "spravne": ["A", "B", "C", "E"],
167
+ "body": 1
168
+ },
169
+ {
170
+ "q": "Proč jsou halucinace v akademii zvlášť problematické?",
171
+ "opts": [
172
+ "A) Jedna vymyšlená citace diskredituje celou práci",
173
+ "B) V nových modelech již vyřešeny",
174
+ "C) AI prezentuje vymyšlené info přesvědčivě",
175
+ "D) Týkají se především citací a faktů",
176
+ "E) Jsou vždy snadno rozpoznatelné"
177
+ ],
178
+ "spravne": ["A", "C", "D"],
179
+ "body": 1
180
+ },
181
+ {
182
+ "q": "Rozdíl mezi 'asistencí' a 'nahrazením úsudku'?",
183
+ "opts": [
184
+ "A) Asistence = AI strukturuje MOJE myšlenky",
185
+ "B) Nahrazení = AI vytváří závěry které přebírám",
186
+ "C) V akademii irelevantní",
187
+ "D) Asistence = finální odpovědnost na mně",
188
+ "E) Oba postupy stejně přijatelné"
189
+ ],
190
+ "spravne": ["A", "B", "D"],
191
+ "body": 1
192
+ },
193
+ {
194
+ "q": "Jak správně pracovat s AI a GDPR v akademickém výzkumu?",
195
+ "opts": [
196
+ "A) Anonymizovat data před nahráním",
197
+ "B) Data z výzkumu lze nahrávat bez omezení",
198
+ "C) Necitlivá data respondentů do veřejných AI",
199
+ "D) Enterprise AI nabízí lepší ochranu",
200
+ "E) GDPR se na akademii nevztahuje"
201
+ ],
202
+ "spravne": ["A", "C", "D"],
203
+ "body": 1
204
+ },
205
+ {
206
+ "q": "Proč je pro akademii doporučena angličtina?",
207
+ "opts": [
208
+ "A) AI trénovány primárně na anglických akademických textech",
209
+ "B) Kvalita v češtině a angličtině je stejná",
210
+ "C) Pro vědu přesnější odpovědi v angličtině",
211
+ "D) Pro admin práci lepší čeština",
212
+ "E) Angličtina není důležitá"
213
+ ],
214
+ "spravne": ["A", "C", "D"],
215
+ "body": 1
216
+ },
217
+ # Metodologické 7-12 (po 1.5 bodu)
218
+ {
219
+ "q": "Které použití AI je přijatelné a které ne?",
220
+ "opts": [
221
+ "A) PŘIJATELNÉ: Návrh struktury mých myšlenek",
222
+ "B) PŘIJATELNÉ: Generování závěrů výzkumu",
223
+ "C) PŘIJATELNÉ: Identifikace slabých míst argumentace",
224
+ "D) NEPŘIJATELNÉ: Auto-psaní sekcí bez kontroly",
225
+ "E) PŘIJATELNÉ: Delegování hodnotových soudů"
226
+ ],
227
+ "spravne": ["A", "C", "D"],
228
+ "body": 1.5
229
+ },
230
+ {
231
+ "q": "Jak pracovat s epistemickou nejistotou?",
232
+ "opts": [
233
+ "A) Požadovat explicitní míru jistoty",
234
+ "B) Důvěřovat autoritativnímu tónu AI",
235
+ "C) Ověřovat tvrzení z primárních zdrojů",
236
+ "D) Žádat alternativní interpretace",
237
+ "E) AI jako konečný arbitr"
238
+ ],
239
+ "spravne": ["A", "C", "D"],
240
+ "body": 1.5
241
+ },
242
+ {
243
+ "q": "Jak správně pracovat se zdroji a citacemi?",
244
+ "opts": [
245
+ "A) AI často vymýšlí věrohodné citace",
246
+ "B) Každou citaci ověřit v databázích",
247
+ "C) Answer pressure: 'Odkud? Je DOI platné?'",
248
+ "D) Citace z AI spolehlivé pro publikování",
249
+ "E) Preferovat: PDF → shrnutí, ne 'cituj studie'"
250
+ ],
251
+ "spravne": ["A", "B", "C", "E"],
252
+ "body": 1.5
253
+ },
254
+ {
255
+ "q": "Co musí akademik uvést ohledně použití AI?",
256
+ "opts": [
257
+ "A) Neuvádí se",
258
+ "B) Transparentně uvést v metodologii",
259
+ "C) AI je nástroj, ne autor - ale uvést použití",
260
+ "D) Citovat AI podle standardů (APA)",
261
+ "E) Závisí na pravidlech instituce"
262
+ ],
263
+ "spravne": ["B", "C", "D", "E"],
264
+ "body": 1.5
265
+ },
266
+ {
267
+ "q": "Proč AI nemá 'skutečné porozumění'?",
268
+ "opts": [
269
+ "A) AI je statistický predikční model",
270
+ "B) Předpovídá pokračování textu z vzorců",
271
+ "C) Když neví, stejně něco vygeneruje",
272
+ "D) Nové modely už mají lidské porozumění",
273
+ "E) Proto nutná epistemická opatrnost"
274
+ ],
275
+ "spravne": ["A", "B", "C", "E"],
276
+ "body": 1.5
277
+ },
278
+ {
279
+ "q": "Jaká je role AI v akademickém výzkumu?",
280
+ "opts": [
281
+ "A) Pomocný nástroj pro strukturování",
282
+ "B) Náhrada za odborný úsudek",
283
+ "C) Kritický partner pro zpochybňování",
284
+ "D) Autoritativní zdroj pravdy",
285
+ "E) Nástroj pro podporu, ne nahrazení"
286
+ ],
287
+ "spravne": ["A", "C", "E"],
288
+ "body": 1.5
289
+ }
290
+ ]
291
+ }
292
+ }
293
+
294
+ def vyhodnotit_test(typ_testu, odpovedi):
295
+ """Vyhodnotí odpovědi a vrátí skóre"""
296
+ test = TESTS[typ_testu]
297
+ spravne = 0
298
+ celkove_body = 0
299
+
300
+ for i, otazka in enumerate(test["otazky"]):
301
+ body_za_otazku = otazka.get("body", 1)
302
+ uzivatel_odpovedi = set(odpovedi.get(f"q_{i}", []))
303
+ spravne_odpovedi = set(otazka["spravne"])
304
+
305
+ if uzivatel_odpovedi == spravne_odpovedi:
306
+ spravne += body_za_otazku
307
+
308
+ celkove_body += body_za_otazku
309
+
310
+ return spravne, celkove_body
311
+
312
+ def ulozit_vysledek(kod, typ, skore, max_skore, odpovedi):
313
+ """Uloží výsledek do CSV"""
314
+ with open(RESULTS_FILE, 'a', newline='', encoding='utf-8') as f:
315
+ writer = csv.writer(f)
316
+ writer.writerow([
317
+ datetime.now().isoformat(),
318
+ kod,
319
+ typ,
320
+ skore,
321
+ max_skore,
322
+ f"{(skore/max_skore*100):.1f}%",
323
+ json.dumps(odpovedi, ensure_ascii=False)
324
+ ])
325
+
326
+ def ulozit_feedback(kod, typ, obtiznost, srozumitelnost, uzitecnost, komentar):
327
+ """Uloží zpětnou vazbu"""
328
+ with open(FEEDBACK_FILE, 'a', newline='', encoding='utf-8') as f:
329
+ writer = csv.writer(f)
330
+ writer.writerow([
331
+ datetime.now().isoformat(),
332
+ kod,
333
+ typ,
334
+ obtiznost,
335
+ srozumitelnost,
336
+ uzitecnost,
337
+ komentar
338
+ ])
339
+
340
+ # Gradio UI
341
+ with gr.Blocks(title="Test AI znalostí KTF UK", theme=gr.themes.Soft()) as demo:
342
+ gr.Markdown("# 🎓 Test znalostí: Generativní AI")
343
+ gr.Markdown("**Katolická teologická fakulta UK, Praha 2025**")
344
+
345
+ # State
346
+ user_kod = gr.State("")
347
+ user_typ = gr.State("")
348
+ user_odpovedi = gr.State({})
349
+
350
+ with gr.Tab("🔐 Začátek"):
351
+ gr.Markdown("### Vítejte v testu znalostí generativní AI")
352
+ gr.Markdown("Pro zahájení testu zadejte váš unikátní kód a vyberte typ testu.")
353
+
354
+ kod_input = gr.Textbox(
355
+ label="Váš unikátní kód",
356
+ placeholder="Např: KTF2025-001",
357
+ info="Tento kód obdržíte od organizátora"
358
+ )
359
+
360
+ typ_radio = gr.Radio(
361
+ choices=[
362
+ ("STAFF - Pro administrativní pracovníky (10 otázek)", "STAFF"),
363
+ ("ACADEMIC - Pro výzkumníky (12 otázek)", "ACADEMIC")
364
+ ],
365
+ label="Typ testu",
366
+ info="Vyberte test odpovídající vaší roli"
367
+ )
368
+
369
+ start_btn = gr.Button("Začít test", variant="primary", size="lg")
370
+ start_msg = gr.Markdown("")
371
+
372
+ with gr.Tab("📝 Test") as test_tab:
373
+ test_info = gr.Markdown("")
374
+
375
+ otazky_ui = []
376
+ for i in range(12): # Max počet otázek
377
+ with gr.Group(visible=False) as q_group:
378
+ q_text = gr.Markdown("")
379
+ q_check = gr.CheckboxGroup(label="Vyberte VŠECHNY správné odpovědi")
380
+ otazky_ui.append((q_group, q_text, q_check))
381
+
382
+ submit_btn = gr.Button("Odeslat test", variant="primary", size="lg", visible=False)
383
+
384
+ with gr.Tab("📊 Výsledky") as results_tab:
385
+ result_md = gr.Markdown("")
386
+
387
+ gr.Markdown("### 💬 Zpětná vazba")
388
+ gr.Markdown("Pomozte nám zlepšit test:")
389
+
390
+ obtiznost = gr.Radio(
391
+ choices=["Příliš snadný", "Přiměřený", "Příliš těžký"],
392
+ label="Obtížnost testu"
393
+ )
394
+ srozumitelnost = gr.Radio(
395
+ choices=["Výborná", "Dobrá", "Špatná"],
396
+ label="Srozumitelnost otázek"
397
+ )
398
+ uzitecnost = gr.Radio(
399
+ choices=["Velmi užitečné", "Užitečné", "Málo užitečné"],
400
+ label="Užitečnost pro praxi"
401
+ )
402
+ komentar = gr.Textbox(
403
+ label="Váš komentář (nepovinné)",
404
+ placeholder="Sdílejte své postřehy...",
405
+ lines=3
406
+ )
407
+
408
+ feedback_btn = gr.Button("Odeslat zpětnou vazbu", variant="secondary")
409
+ feedback_msg = gr.Markdown("")
410
+
411
+ # Logika
412
+ def start_test(kod, typ):
413
+ if not kod or not typ:
414
+ return {
415
+ start_msg: "❌ Vyplňte prosím kód i typ testu",
416
+ user_kod: "",
417
+ user_typ: ""
418
+ }
419
+
420
+ test = TESTS[typ]
421
+ num_q = len(test["otazky"])
422
+
423
+ # Připrav UI pro otázky
424
+ updates = {
425
+ start_msg: f"✅ Test zahájen! Přejděte na záložku 'Test'",
426
+ user_kod: kod,
427
+ user_typ: typ,
428
+ test_info: f"## {test['nazev']}\n\n{test['popis']}\n\n**Počet otázek:** {num_q}"
429
+ }
430
+
431
+ # Zobraz otázky
432
+ for i in range(12):
433
+ if i < num_q:
434
+ q = test["otazky"][i]
435
+ updates[otazky_ui[i][0]] = gr.update(visible=True)
436
+ updates[otazky_ui[i][1]] = f"### Otázka {i+1}\n\n{q['q']}"
437
+ updates[otazky_ui[i][2]] = gr.update(choices=q["opts"], value=[])
438
+ else:
439
+ updates[otazky_ui[i][0]] = gr.update(visible=False)
440
+
441
+ updates[submit_btn] = gr.update(visible=True)
442
+
443
+ return updates
444
+
445
+ def submit_test(kod, typ, *args):
446
+ if not kod or not typ:
447
+ return "❌ Chyba: Test nebyl správně zahájen"
448
+
449
+ # Sesbírej odpovědi
450
+ test = TESTS[typ]
451
+ odpovedi = {}
452
+ for i in range(len(test["otazky"])):
453
+ odpovedi[f"q_{i}"] = args[i] if i < len(args) else []
454
+
455
+ # Vyhodnoť
456
+ skore, max_skore = vyhodnotit_test(typ, odpovedi)
457
+ procenta = (skore / max_skore * 100)
458
+
459
+ # Ulož
460
+ ulozit_vysledek(kod, typ, skore, max_skore, odpovedi)
461
+
462
+ # Výsledek
463
+ if typ == "STAFF":
464
+ uspech = skore >= 7
465
+ pozadavek = "min. 7 bodů"
466
+ else:
467
+ uspech = skore >= 8 # Zjednodušená podmínka
468
+ pozadavek = "min. 8 bodů"
469
+
470
+ result = f"""
471
+ ## {'✅ Úspěch!' if uspech else '❌ Neúspěch'}
472
+
473
+ **Váš výsledek:** {skore:.1f} / {max_skore} bodů ({procenta:.1f}%)
474
+
475
+ **Požadavek:** {pozadavek}
476
+
477
+ {'🎉 Gratulujeme! Test jste úspěšně absolvovali.' if uspech else '😔 Bohužel jste nesplnili minimální požadavek. Doporučujeme prostudovat příručku a zkusit to znovu.'}
478
+
479
+ ---
480
+
481
+ **Kód účastníka:** {kod}
482
+ **Datum:** {datetime.now().strftime('%d.%m.%Y %H:%M')}
483
+ """
484
+
485
+ return result
486
+
487
+ def submit_feedback(kod, typ, obt, sroz, uzit, kom):
488
+ if not kod:
489
+ return "❌ Chyba p��i odesílání zpětné vazby"
490
+
491
+ ulozit_feedback(kod, typ, obt, sroz, uzit, kom)
492
+ return "✅ Děkujeme za zpětnou vazbu!"
493
+
494
+ # Events
495
+ start_btn.click(
496
+ fn=start_test,
497
+ inputs=[kod_input, typ_radio],
498
+ outputs=[start_msg, user_kod, user_typ, test_info] +
499
+ [item for group in otazky_ui for item in group] +
500
+ [submit_btn]
501
+ )
502
+
503
+ submit_btn.click(
504
+ fn=submit_test,
505
+ inputs=[user_kod, user_typ] + [q[2] for q in otazky_ui],
506
+ outputs=[result_md]
507
+ )
508
+
509
+ feedback_btn.click(
510
+ fn=submit_feedback,
511
+ inputs=[user_kod, user_typ, obtiznost, srozumitelnost, uzitecnost, komentar],
512
+ outputs=[feedback_msg]
513
+ )
514
+
515
+ if __name__ == "__main__":
516
+ demo.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio==4.44.0