BlindKnifemaker commited on
Commit
43cfdee
·
verified ·
1 Parent(s): 35fcbab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +351 -64
app.py CHANGED
@@ -15,35 +15,289 @@ for f, cols in [(RESULTS, ['cas','kod','typ','skore','max','procenta','odpovedi'
15
 
16
  TESTS = {
17
  "STAFF": {
18
- "nazev": "STAFF - Administrativní pracovníci",
19
  "questions": [
20
- {"q": "Struktura promptu je: Role + Kontext + Úkol + Formát", "opts": ["A) Ano, správně", "B) Ne, jen úkol", "C) Role zlepšuje kvalitu", "D) Formát nedůležitý", "E) Kontext pomáhá"], "ans": ["A","C","E"]},
21
- {"q": "Zero-shot prompting znamená:", "opts": ["A) Jeden příklad", "B) Bez příkladů", "C) Tři příklady", "D) Nejjednodušší forma", "E) Nejlepší výsledky"], "ans": ["B","D"]},
22
- {"q": "Answer pressure testing je:", "opts": ["A) Rychlost", "B) Kontrola odpovědí AI", "C) 'Jsi si jistý?'", "D) Odhaluje halucinace", "E) Horší kvalita"], "ans": ["B","C","D"]},
23
- {"q": "AI v kanceláři lze použít pro:", "opts": ["A) Shrnutí dokumentů", "B) Extrakci dat", "C) Anonymizaci", "D) Fyzickou archivaci", "E) Překlady"], "ans": ["A","B","C","E"]},
24
- {"q": "Halucinace AI:", "opts": ["A) Vymýšlí věrohodně", "B) Snadno vidět", "C) Ověřovat fakta", "D) Answer pressure pomáhá", "E) Nové modely OK"], "ans": ["A","C","D"]},
25
- {"q": "Token:", "opts": ["A) ~4 znaky", "B) Jednotka zpracování", "C) Měna", "D) Modely mají limit", "E) Totéž co slovo"], "ans": ["A","B","D"]},
26
- {"q": "GDPR+AI:", "opts": ["A) Anonymizovat", "B) Nevztahuje se", "C) Ne citlivá do veřejných", "D) Znát politiku", "E) Lze vše"], "ans": ["A","C","D"]},
27
- {"q": "Jazyk:", "opts": ["A) Češtinu uvést", "B) Auto rozpozná", "C) Věda→angličtina", "D) Stejná kvalita", "E) Kombinovat OK"], "ans": ["A","C","E"]},
28
- {"q": "Chain-of-thought:", "opts": ["A) Postupné kroky", "B) Nejrychlejší", "C) Analýzy", "D) '1)témata 2)problémy'", "E) Ne pro analytiku"], "ans": ["A","C","D"]},
29
- {"q": "Role-playing:", "opts": ["A) Přiřadit roli", "B) 'Jsi HR'", "C) Bez vlivu", "D) Přizpůsobí jazyk", "E) Jen zábava"], "ans": ["A","B","D"]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  ]
31
  },
32
  "ACADEMIC": {
33
- "nazev": "ACADEMIC - Výzkumní pracovníci",
34
  "questions": [
35
- {"q": "Akademický prompt:", "opts": ["A) Role+Kontext+Úkol+Formát+Omezení", "B) Jen úkol", "C) Fakta/interpretace", "D) Míra jistoty", "E) Formát nedůležitý"], "ans": ["A","C","D"], "pts": 1},
36
- {"q": "Answer pressure akademie:", "opts": ["A) Zpochybňování", "B) 'Jsi jistý?'", "C) Halucinace", "D) Méně důležitý", "E) Přiznat nejistotu"], "ans": ["A","B","C","E"], "pts": 1},
37
- {"q": "Halucinace akademie:", "opts": ["A) 1 citace=konec", "B) Vyřešeny", "C) Přesvědčivé", "D) Hlavně citace", "E) Vidět"], "ans": ["A","C","D"], "pts": 1},
38
- {"q": "Asistence×nahrazení:", "opts": ["A) Asistence=moje", "B) Nahrazení=AI závěry", "C) Irelevantní", "D) Má odpovědnost", "E) Stejné"], "ans": ["A","B","D"], "pts": 1},
39
- {"q": "GDPR výzkum:", "opts": ["A) Anonymizovat", "B) Lze vše", "C) Ne citlivá", "D) Enterprise lepší", "E) Nevztahuje"], "ans": ["A","C","D"], "pts": 1},
40
- {"q": "Angličtina:", "opts": ["A) Tréninková data", "B) Stejné", "C) Přesnější věda", "D) Admin CZ", "E) Nedůležité"], "ans": ["A","C","D"], "pts": 1},
41
- {"q": "Přijatelné:", "opts": ["A) OK: Struktura", "B) OK: Závěry", "C) OK: Slabá místa", "D) NE: Auto-psaní", "E) OK: Hodnoty AI"], "ans": ["A","C","D"], "pts": 1.5},
42
- {"q": "Nejistota:", "opts": ["A) Požadovat jistotu", "B) Důvěřovat tónu", "C) Ověřovat", "D) Alternativy", "E) AI arbitr"], "ans": ["A","C","D"], "pts": 1.5},
43
- {"q": "Citace:", "opts": ["A) AI vymýšlí", "B) Ověřit", "C) 'DOI OK?'", "D) Spolehlivé", "E) PDF→shrnutí"], "ans": ["A","B","C","E"], "pts": 1.5},
44
- {"q": "Transparentnost:", "opts": ["A) Ne", "B) Metodologie", "C) Nástroj=uvést", "D) Citovat APA", "E) Závisí"], "ans": ["B","C","D","E"], "pts": 1.5},
45
- {"q": "Porozumění:", "opts": ["A) Statistika", "B) Vzorce", "C) Generuje i když neví", "D) Lidské", "E) Opatrnost"], "ans": ["A","B","C","E"], "pts": 1.5},
46
- {"q": "Role AI:", "opts": ["A) Nástroj", "B) Náhrada", "C) Partner", "D) Pravda", "E) Podpora"], "ans": ["A","C","E"], "pts": 1.5}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  ]
48
  }
49
  }
@@ -75,14 +329,18 @@ def get_file(pwd, which):
75
  return file, f"✅ {file} připraven ke stažení"
76
 
77
  with gr.Blocks(title="Test AI KTF") as app:
78
- gr.Markdown("# 🎓 Test znalostí: Generativní AI\n**KTF UK Praha 2025**")
79
  kod_s, typ_s = gr.State(""), gr.State("")
80
 
81
  with gr.Tab("🔐 Start"):
82
  gr.Markdown("### Zahájení testu")
83
- kod = gr.Textbox(label="Váš kód", placeholder="KTF2025-001")
84
- typ = gr.Radio([("STAFF - Admin (10 otázek)", "STAFF"), ("ACADEMIC - Výzkum (12 otázek)", "ACADEMIC")], label="Typ")
85
- go = gr.Button("Začít test", variant="primary")
 
 
 
 
86
  msg = gr.Markdown("")
87
 
88
  with gr.Tab("📝 Test"):
@@ -91,81 +349,110 @@ with gr.Blocks(title="Test AI KTF") as app:
91
  for i in range(12):
92
  with gr.Group(visible=False) as g:
93
  qt = gr.Markdown("")
94
- qc = gr.CheckboxGroup(label="⚠️ Označte VŠECHNY správné")
95
- qs.append((g,qt,qc))
96
- send = gr.Button("Odeslat test", variant="primary", visible=False)
 
 
97
 
98
  with gr.Tab("📊 Výsledky"):
99
  res = gr.Markdown("")
100
 
101
  gr.Markdown("---")
102
- gr.Markdown("### 💬 Zpětná vazba (2 minuty)")
103
- gr.Markdown("**Test:**")
104
- obt_t = gr.Radio(["Snadný","OK","Těžký"], label="Obtížnost")
105
- sroz_t = gr.Radio(["Výborná","Dobrá","Špatná"], label="Jasnost otázek")
106
- uzit_t = gr.Radio(["Velmi","Středně","Málo"], label="Užitečnost")
107
 
108
- gr.Markdown("**Výuka/kurz AI:**")
109
- obt_v = gr.Radio(["Snadná","OK","Těžká"], label="Obtížnost")
110
- sroz_v = gr.Radio(["Výborná","Dobrá","Špatná"], label="Jasnost výkladu")
111
- uzit_v = gr.Radio(["Velmi","Středně","Málo"], label="Užitečnost pro praxi")
112
 
113
- kom = gr.Textbox(label="Komentář (nepovinné)", placeholder="Vaše postřehy...", lines=2)
 
 
 
 
 
114
  fb = gr.Button("Odeslat zpětnou vazbu", variant="secondary")
115
  fb_msg = gr.Markdown("")
116
 
117
  with gr.Tab("👨‍💼 Admin"):
118
- gr.Markdown("### 🔒 Stahování (heslo)")
119
- pwd = gr.Textbox(label="Heslo", type="password", placeholder="Výchozí: admin")
 
120
  with gr.Row():
121
- dlr = gr.Button("Stáhnout výsledky")
122
- dlf = gr.Button("Stáhnout zpětnou vazbu")
123
- dl = gr.File(label="CSV soubor")
124
  dlm = gr.Markdown("")
 
125
 
126
  def start(k, t):
127
  if not k or not t:
128
- return {msg: "❌ Vyplňte kód i typ", kod_s: "", typ_s: ""}
129
  test = TESTS[t]
130
- upd = {msg: f"✅ Test zahájen! **→ Přejděte na záložku 'Test'**", kod_s: k, typ_s: t,
131
- info: f"## {test['nazev']}\n\n**Otázek:** {len(test['questions'])}\n\n⚠️ U každé otázky označte VŠECHNY správné odpovědi!",
132
- send: gr.update(visible=True)}
 
 
 
 
 
133
  for i in range(12):
134
  if i < len(test["questions"]):
135
  q = test["questions"][i]
136
  upd[qs[i][0]] = gr.update(visible=True)
137
- upd[qs[i][1]] = f"### {i+1}. {q['q']}"
138
- upd[qs[i][2]] = gr.update(choices=q["opts"], value=[])
 
139
  else:
140
  upd[qs[i][0]] = gr.update(visible=False)
141
  return upd
142
 
143
  def submit(k, t, *a):
144
- if not k: return "❌ Chyba"
 
 
145
  ans = {f"q_{i}": a[i] for i in range(len(TESTS[t]["questions"]))}
146
  sc, mx = score(t, ans)
147
  save_result(k, t, sc, mx, ans)
148
  ok = sc >= (7 if t=="STAFF" else 8)
149
- poz = "7 bodů" if t=="STAFF" else "8 bodů"
150
- return f"""## {'✅ Úspěch!' if ok else '❌ Neúspěch'}
 
151
 
152
- **Výsledek:** {sc:.1f}/{mx} bodů ({sc/mx*100:.1f}%)
153
- **Požadavek:** min. {poz}
154
 
155
- {'🎉 Gratulujeme!' if ok else '😔 Zkuste znovu po prostudování materiálů.'}
156
 
157
  ---
158
- **Kód:** {k} | **Datum:** {datetime.now().strftime('%d.%m.%Y %H:%M')}
 
 
 
 
159
 
160
  ---
161
 
162
- ### ⬇️ **PROSÍM, VYPLŇTE ZPĚTNOU VAZBU NÍŽE**
163
- Pomozte nám zlepšit test i výuku. Anonymní, zabere 2 minuty. Děkujeme! 🙏"""
 
 
 
 
 
 
 
 
 
164
 
165
- go.click(start, [kod,typ], [msg,kod_s,typ_s,info]+[x for g in qs for x in g]+[send])
166
- send.click(submit, [kod_s,typ_s]+[q[2] for q in qs], res)
167
- fb.click(lambda k,t,ot,st,ut,ov,sv,uv,c: (save_fb(k,t,ot,st,ut,ov,sv,uv,c), "✅ Děkujeme za zpětnou vazbu!")[1] if k else "❌ Nelze odeslat",
168
  [kod_s,typ_s,obt_t,sroz_t,uzit_t,obt_v,sroz_v,uzit_v,kom], fb_msg)
 
169
  dlr.click(lambda p: get_file(p,"r"), pwd, [dl,dlm])
170
  dlf.click(lambda p: get_file(p,"f"), pwd, [dl,dlm])
171
 
 
15
 
16
  TESTS = {
17
  "STAFF": {
18
+ "nazev": "Test pro administrativní pracovníky (STAFF)",
19
  "questions": [
20
+ {
21
+ "q": "Jaká je doporučená struktura efektivního promptu pro práci s AI?",
22
+ "ctx": "Prompt je instrukce, kterou AI zadáváte. Jeho struktura ovlivňuje kvalitu odpovědí.",
23
+ "opts": [
24
+ "A) Role + Kontext + Úkol + Formát",
25
+ "B) Pouze úkol, ostatní AI domyslí sama",
26
+ "C) Poskytnutí jasné role AI zlepšuje kvalitu odpovědí",
27
+ "D) Formát výstupu není důležitý",
28
+ "E) Kontext pomáhá AI lépe pochopit situaci"
29
+ ],
30
+ "ans": ["A","C","E"]
31
+ },
32
+ {
33
+ "q": "Co přesně znamená termín 'zero-shot prompting'?",
34
+ "ctx": "Zero-shot je základní technika práce s AI, kdy modelu poskytujeme pouze instrukci bez dalších příkladů.",
35
+ "opts": [
36
+ "A) Poskytnutí jednoho vzorového příkladu",
37
+ "B) Zadání instrukce bez jakýchkoliv příkladů",
38
+ "C) Poskytnutí tří vzorových příkladů",
39
+ "D) Nejjednodušší forma práce s AI",
40
+ "E) Vždy poskytuje nejlepší výsledky"
41
+ ],
42
+ "ans": ["B","D"]
43
+ },
44
+ {
45
+ "q": "Co je 'answer pressure testing' a k čemu slouží?",
46
+ "ctx": "Answer pressure testing je technika, kterou testujeme spolehlivost odpovědí AI a snižujeme riziko chyb.",
47
+ "opts": [
48
+ "A) Technika pro zrychlení generování odpovědí",
49
+ "B) Žádost, aby AI zkontrolovala a zdůvodnila své odpovědi",
50
+ "C) Příklad: 'Jsi si tímto výsledkem jistý? Zkontroluj svoje úvahy.'",
51
+ "D) Pomáhá odhalit případné halucinace AI",
52
+ "E) Snižuje kvalitu odpovědí tím, že AI zmate"
53
+ ],
54
+ "ans": ["B","C","D"]
55
+ },
56
+ {
57
+ "q": "Které z následujících úkolů lze bezpečně řešit pomocí AI v kancelářské práci?",
58
+ "ctx": "AI je užitečná pro mnoho úkolů, ale ne všechny jsou pro ni vhodné nebo bezpečné.",
59
+ "opts": [
60
+ "A) Shrnutí dlouhých dokumentů do kratší formy",
61
+ "B) Extrakce konkrétních informací (jména, data, částky) z dokumentů",
62
+ "C) Anonymizace osobních údajů v dokumentech",
63
+ "D) Fyzická archivace papírových dokumentů",
64
+ "E) Překlad textů a změna stylu komunikace"
65
+ ],
66
+ "ans": ["A","B","C","E"]
67
+ },
68
+ {
69
+ "q": "Co přesně jsou 'halucinace' v kontextu AI systémů?",
70
+ "ctx": "Halucinace jsou jedním z nejzáva��nějších rizik při práci s AI a je důležité jim porozumět.",
71
+ "opts": [
72
+ "A) AI vymýšlí informace, které vypadají věrohodně, ale jsou nepravdivé",
73
+ "B) Halucinace jsou vždy snadno rozpoznatelné",
74
+ "C) Je nezbytné vždy ověřovat důležitá fakta z jiných zdrojů",
75
+ "D) Answer pressure testing může pomoci odhalit halucinace",
76
+ "E) Nové modely AI už halucinace nemají"
77
+ ],
78
+ "ans": ["A","C","D"]
79
+ },
80
+ {
81
+ "q": "Co je 'token' a proč je tento pojem důležitý?",
82
+ "ctx": "Token je základní jednotka, se kterou AI systémy pracují. Pochopení tokenů je klíčové pro efektivní práci s AI.",
83
+ "opts": [
84
+ "A) Token odpovídá přibližně 4 znakům textu",
85
+ "B) Token je základní jednotka zpracování textu v AI",
86
+ "C) Token je měna pro placení AI služeb",
87
+ "D) AI modely mají limit na počet tokenů",
88
+ "E) Token je totéž co jedno slovo"
89
+ ],
90
+ "ans": ["A","B","D"]
91
+ },
92
+ {
93
+ "q": "Jak správně pracovat s AI při respektování GDPR?",
94
+ "ctx": "GDPR chrání osobní údaje občanů EU. Při práci s AI je nutné dodržovat tyto právní požadavky.",
95
+ "opts": [
96
+ "A) Anonymizovat všechny osobní údaje před nahráním do AI",
97
+ "B) GDPR se na práci s AI nevztahuje",
98
+ "C) Nikdy neposílat citlivá data do veřejných AI systémů",
99
+ "D) Znát politiku zpracování dat AI platformy",
100
+ "E) Osobní údaje lze do AI nahrávat bez omezení"
101
+ ],
102
+ "ans": ["A","C","D"]
103
+ },
104
+ {
105
+ "q": "Jak správně pracovat s češtinou vs. angličtinou při použití AI?",
106
+ "ctx": "Volba jazyka ovlivňuje kvalitu odpovědí AI systémů, protože byly trénovány primárně na anglických datech.",
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
+ "ans": ["A","C","E"]
115
+ },
116
+ {
117
+ "q": "Co znamená 'chain-of-thought prompting' a kdy ho použít?",
118
+ "ctx": "Chain-of-thought je pokročilá technika, kdy žádáme AI o postupné vysvětlení jednotlivých kroků řešení.",
119
+ "opts": [
120
+ "A) Žádost o postupné vysvětlení kroků",
121
+ "B) Nejrychlejší způsob generování",
122
+ "C) Užitečné pro komplexní analýzy",
123
+ "D) Příklad: 'Analyzuj: 1) témata 2) problémy 3) řešení'",
124
+ "E) Nevhodné pro analytické úlohy"
125
+ ],
126
+ "ans": ["A","C","D"]
127
+ },
128
+ {
129
+ "q": "Co je 'role-playing' v kontextu práce s AI?",
130
+ "ctx": "Role-playing je technika, kdy AI přiřazujeme konkrétní roli či identitu, což ovlivňuje styl a obsah odpovědí.",
131
+ "opts": [
132
+ "A) AI přiřadíte konkrétní roli",
133
+ "B) Příklad: 'Jsi zkušený HR manažer s 20 lety praxe'",
134
+ "C) Role nijak neovlivňuje odpovědi",
135
+ "D) Role pomáhá přizpůsobit jazyk a odbornost",
136
+ "E) Používá se pouze pro zábavu"
137
+ ],
138
+ "ans": ["A","B","D"]
139
+ }
140
  ]
141
  },
142
  "ACADEMIC": {
143
+ "nazev": "Test pro akademické pracovníky (ACADEMIC)",
144
  "questions": [
145
+ {
146
+ "q": "Jaká je struktura akademického promptu?",
147
+ "ctx": "Akademická práce vyžaduje přesnější a rigoróznější strukturu promptů než běžné použití AI.",
148
+ "opts": [
149
+ "A) Role + Kontext + Úkol + Formát + Omezení",
150
+ "B) Pouze úkol",
151
+ "C) Požadavek na rozlišení fakta/interpretace",
152
+ "D) Žádost o označení míry jistoty",
153
+ "E) Formát není důležitý"
154
+ ],
155
+ "ans": ["A","C","D"],
156
+ "pts": 1
157
+ },
158
+ {
159
+ "q": "Co je 'answer pressure testing' a proč je v akademii kritický?",
160
+ "ctx": "V akademickém kontextu je spolehlivost informací zásadní, proto je answer pressure testing klíčovou technikou.",
161
+ "opts": [
162
+ "A) Technika systematického zpochybňování",
163
+ "B) Příklad: 'Jsi si jistý? Odkud to? Alternativy?'",
164
+ "C) Pomáhá odhalit halucinace",
165
+ "D) V akademii méně důležitý než v kanceláři",
166
+ "E) Nutí AI přiznat nejistotu"
167
+ ],
168
+ "ans": ["A","B","C","E"],
169
+ "pts": 1
170
+ },
171
+ {
172
+ "q": "Proč jsou halucinace v akademii zvlášť problematické?",
173
+ "ctx": "V akademickém výzkumu může jediná chyba diskreditovat celou práci. Halucinace AI představují závažné riziko.",
174
+ "opts": [
175
+ "A) Jedna vymyšlená citace diskredituje celou práci",
176
+ "B) V nových modelech již vyřešeny",
177
+ "C) AI prezentuje vymyšlené info přesvědčivě",
178
+ "D) Týkají se především citací a faktů",
179
+ "E) Jsou vždy snadno rozpoznatelné"
180
+ ],
181
+ "ans": ["A","C","D"],
182
+ "pts": 1
183
+ },
184
+ {
185
+ "q": "Rozdíl mezi 'asistencí' a 'nahrazením úsudku'?",
186
+ "ctx": "V akademické práci je klíčové rozlišovat, kdy AI pomáhá a kdy za nás myslí. To má etické i metodologické důsledky.",
187
+ "opts": [
188
+ "A) Asistence = AI strukturuje MOJE myšlenky",
189
+ "B) Nahrazení = AI vytváří závěry které přebírám",
190
+ "C) V akademii irelevantní",
191
+ "D) Asistence = finální odpovědnost na mně",
192
+ "E) Oba postupy stejně přijatelné"
193
+ ],
194
+ "ans": ["A","B","D"],
195
+ "pts": 1
196
+ },
197
+ {
198
+ "q": "Jak správně pracovat s AI a GDPR v akademickém výzkumu?",
199
+ "ctx": "Akademický výzkum často pracuje s citlivými daty respondentů. GDPR stanovuje přísné požadavky na jejich ochranu.",
200
+ "opts": [
201
+ "A) Anonymizovat data před nahráním",
202
+ "B) Data z výzkumu lze nahrávat bez omezení",
203
+ "C) Necitlivá data respondentů do veřejných AI",
204
+ "D) Enterprise AI nabízí lepší ochranu",
205
+ "E) GDPR se na akademii nevztahuje"
206
+ ],
207
+ "ans": ["A","C","D"],
208
+ "pts": 1
209
+ },
210
+ {
211
+ "q": "Proč je pro akademii doporučena angličtina?",
212
+ "ctx": "AI modely byly trénovány primárně na anglických akademických textech, což má důsledky pro kvalitu odpovědí.",
213
+ "opts": [
214
+ "A) AI trénovány primárně na anglických akademických textech",
215
+ "B) Kvalita v češtině a angličtině je stejná",
216
+ "C) Pro vědu přesnější odpovědi v angličtině",
217
+ "D) Pro admin práci lepší čeština",
218
+ "E) Angličtina není důležitá"
219
+ ],
220
+ "ans": ["A","C","D"],
221
+ "pts": 1
222
+ },
223
+ {
224
+ "q": "Které použití AI je přijatelné a které ne?",
225
+ "ctx": "V akademické práci existují jasné hranice mezi přijatelným a nepřijatelným použitím AI. Je klíčové je rozlišovat.",
226
+ "opts": [
227
+ "A) PŘIJATELNÉ: Návrh struktury mých myšlenek",
228
+ "B) PŘIJATELNÉ: Generování závěrů výzkumu",
229
+ "C) PŘIJATELNÉ: Identifikace slabých míst argumentace",
230
+ "D) NEPŘIJATELNÉ: Auto-psaní sekcí bez kontroly",
231
+ "E) PŘIJATELNÉ: Delegování hodnotových soudů"
232
+ ],
233
+ "ans": ["A","C","D"],
234
+ "pts": 1.5
235
+ },
236
+ {
237
+ "q": "Jak pracovat s epistemickou nejistotou?",
238
+ "ctx": "AI systémy nemají skutečné porozumění a často si nejsou jisté. Musíme s touto nejistotou pracovat systematicky.",
239
+ "opts": [
240
+ "A) Požadovat explicitní míru jistoty",
241
+ "B) Důvěřovat autoritativnímu tónu AI",
242
+ "C) Ověřovat tvrzení z primárních zdrojů",
243
+ "D) Žádat alternativní interpretace",
244
+ "E) AI jako konečný arbitr"
245
+ ],
246
+ "ans": ["A","C","D"],
247
+ "pts": 1.5
248
+ },
249
+ {
250
+ "q": "Jak správně pracovat se zdroji a citacemi?",
251
+ "ctx": "AI systémy mají tendenci vymýšlet realisticky vypadající citace. To představuje závažné riziko pro akademickou integritu.",
252
+ "opts": [
253
+ "A) AI často vymýšlí věrohodné citace",
254
+ "B) Každou citaci ověřit v databázích",
255
+ "C) Answer pressure: 'Odkud? Je DOI platné?'",
256
+ "D) Citace z AI spolehlivé pro publikování",
257
+ "E) Preferovat: PDF → shrnutí, ne 'cituj studie'"
258
+ ],
259
+ "ans": ["A","B","C","E"],
260
+ "pts": 1.5
261
+ },
262
+ {
263
+ "q": "Co musí akademik uvést ohledně použití AI?",
264
+ "ctx": "Transparentnost je základem akademické integrity. Použití AI nástrojů musí být jasně deklarováno.",
265
+ "opts": [
266
+ "A) Neuvádí se",
267
+ "B) Transparentně uvést v metodologii",
268
+ "C) AI je nástroj, ne autor - ale uvést použití",
269
+ "D) Citovat AI podle standardů (APA)",
270
+ "E) Závisí na pravidlech instituce"
271
+ ],
272
+ "ans": ["B","C","D","E"],
273
+ "pts": 1.5
274
+ },
275
+ {
276
+ "q": "Proč AI nemá 'skutečné porozumění'?",
277
+ "ctx": "Pochopení limitů AI je klíčové pro její zodpovědné použití v akademickém kontextu.",
278
+ "opts": [
279
+ "A) AI je statistický predikční model",
280
+ "B) Předpovídá pokračování textu z vzorců",
281
+ "C) Když neví, stejně něco vygeneruje",
282
+ "D) Nové modely už mají lidské porozumění",
283
+ "E) Proto nutná epistemická opatrnost"
284
+ ],
285
+ "ans": ["A","B","C","E"],
286
+ "pts": 1.5
287
+ },
288
+ {
289
+ "q": "Jaká je role AI v akademickém výzkumu?",
290
+ "ctx": "Je důležité správně definovat roli AI v akademické práci - co může a co nemůže dělat.",
291
+ "opts": [
292
+ "A) Pomocný nástroj pro strukturování",
293
+ "B) Náhrada za odborný úsudek",
294
+ "C) Kritický partner pro zpochybňování",
295
+ "D) Autoritativní zdroj pravdy",
296
+ "E) Nástroj pro podporu, ne nahrazení"
297
+ ],
298
+ "ans": ["A","C","E"],
299
+ "pts": 1.5
300
+ }
301
  ]
302
  }
303
  }
 
329
  return file, f"✅ {file} připraven ke stažení"
330
 
331
  with gr.Blocks(title="Test AI KTF") as app:
332
+ gr.Markdown("# 🎓 Test znalostí: Generativní AI\n**Katolická teologická fakulta UK, Praha 2025**")
333
  kod_s, typ_s = gr.State(""), gr.State("")
334
 
335
  with gr.Tab("🔐 Start"):
336
  gr.Markdown("### Zahájení testu")
337
+ gr.Markdown("Pro zahájení zadejte váš unikátní kód a vyberte typ testu.")
338
+ kod = gr.Textbox(label="Váš unikátní kód", placeholder="KTF2025-001", info="Tento kód obdržíte od organizátora")
339
+ typ = gr.Radio([
340
+ ("STAFF - Administrativní pracovníci (10 otázek)", "STAFF"),
341
+ ("ACADEMIC - Výzkumní pracovníci (12 otázek)", "ACADEMIC")
342
+ ], label="Typ testu", info="Vyberte test odpovídající vaší roli")
343
+ go = gr.Button("Začít test", variant="primary", size="lg")
344
  msg = gr.Markdown("")
345
 
346
  with gr.Tab("📝 Test"):
 
349
  for i in range(12):
350
  with gr.Group(visible=False) as g:
351
  qt = gr.Markdown("")
352
+ qctx = gr.Markdown("", elem_classes="question-context")
353
+ qc = gr.CheckboxGroup(label="⚠️ Vyberte VŠECHNY správné odpovědi")
354
+ qs.append((g,qt,qctx,qc))
355
+ send = gr.Button("Odeslat test", variant="primary", size="lg", visible=False)
356
+ send_msg = gr.Markdown("")
357
 
358
  with gr.Tab("📊 Výsledky"):
359
  res = gr.Markdown("")
360
 
361
  gr.Markdown("---")
362
+ gr.Markdown("### 💬 Zpětná vazba")
363
+ gr.Markdown("*Vaše zpětná vazba je anonymní a pomůže nám zlepšit jak test, tak celou výuku.*")
 
 
 
364
 
365
+ gr.Markdown("#### Hodnocení testu:")
366
+ obt_t = gr.Radio(["Příliš snadný", "Přiměřený", "Příliš těžký"], label="Obtížnost testu")
367
+ sroz_t = gr.Radio(["Výborná", "Dobrá", "Špatná"], label="Srozumitelnost otázek")
368
+ uzit_t = gr.Radio(["Velmi užitečný", "Užitečný", "Málo užitečný"], label="Užitečnost testu pro praxi")
369
 
370
+ gr.Markdown("#### Hodnocení výuky (kurzu AI):")
371
+ obt_v = gr.Radio(["Příliš snadná", "Přiměřená", "Příliš těžká"], label="Obtížnost výuky")
372
+ sroz_v = gr.Radio(["Výborná", "Dobrá", "Špatná"], label="Srozumitelnost výkladu")
373
+ uzit_v = gr.Radio(["Velmi užitečná", "Užitečná", "Málo užitečná"], label="Užitečnost pro praxi")
374
+
375
+ kom = gr.Textbox(label="Váš komentář (nepovinné)", placeholder="Sdílejte své postřehy k testu nebo výuce...", lines=3)
376
  fb = gr.Button("Odeslat zpětnou vazbu", variant="secondary")
377
  fb_msg = gr.Markdown("")
378
 
379
  with gr.Tab("👨‍💼 Admin"):
380
+ gr.Markdown("### 🔒 Administrátorský přístup")
381
+ gr.Markdown("*Pouze pro organizátory kurzu - stahování výsledků*")
382
+ pwd = gr.Textbox(label="Admin heslo", type="password", placeholder="Výchozí: admin")
383
  with gr.Row():
384
+ dlr = gr.Button("📥 Stáhnout výsledky testů")
385
+ dlf = gr.Button("📥 Stáhnout zpětnou vazbu")
386
+ dl = gr.File(label="CSV soubor ke stažení")
387
  dlm = gr.Markdown("")
388
+ gr.Markdown("*Pro změnu hesla upravte ADMIN_HASH v app.py*")
389
 
390
  def start(k, t):
391
  if not k or not t:
392
+ return {msg: "❌ Prosím vyplňte kód i typ testu", kod_s: "", typ_s: ""}
393
  test = TESTS[t]
394
+ upd = {
395
+ msg: f" Test byl zahájen! **→ Přejděte na záložku 'Test'**",
396
+ kod_s: k,
397
+ typ_s: t,
398
+ info: f"## {test['nazev']}\n\n**Počet otázek:** {len(test['questions'])}\n\n⚠️ **Důležité:** U každé otázky označte VŠECHNY správné odpovědi!",
399
+ send: gr.update(visible=True),
400
+ send_msg: ""
401
+ }
402
  for i in range(12):
403
  if i < len(test["questions"]):
404
  q = test["questions"][i]
405
  upd[qs[i][0]] = gr.update(visible=True)
406
+ upd[qs[i][1]] = f"### Otázka {i+1}\n\n{q['q']}"
407
+ upd[qs[i][2]] = f"*{q.get('ctx', '')}*"
408
+ upd[qs[i][3]] = gr.update(choices=q["opts"], value=[])
409
  else:
410
  upd[qs[i][0]] = gr.update(visible=False)
411
  return upd
412
 
413
  def submit(k, t, *a):
414
+ if not k:
415
+ return "❌ Chyba: Test nebyl správně zahájen", ""
416
+
417
  ans = {f"q_{i}": a[i] for i in range(len(TESTS[t]["questions"]))}
418
  sc, mx = score(t, ans)
419
  save_result(k, t, sc, mx, ans)
420
  ok = sc >= (7 if t=="STAFF" else 8)
421
+ poz = "minimálně 7 bodů" if t=="STAFF" else "minimálně 8 bodů"
422
+
423
+ result = f"""## {'✅ Gratulujeme! Test úspěšně splněn!' if ok else '❌ Test nesplněn'}
424
 
425
+ **Váš výsledek:** {sc:.1f} / {mx} bodů ({sc/mx*100:.1f}%)
426
+ **Požadavek pro splnění:** {poz}
427
 
428
+ {'🎉 **Úspěšně jste absolvovali test!**' if ok else '😔 Bohužel jste nedosáhli minimálního počtu bodů. Doporučujeme prostudovat materiály a zkusit test znovu.'}
429
 
430
  ---
431
+
432
+ **📊 Podrobnosti:**
433
+ - Kód účastníka: {k}
434
+ - Typ testu: {t}
435
+ - Datum a čas: {datetime.now().strftime('%d.%m.%Y v %H:%M')}
436
 
437
  ---
438
 
439
+ ### ⬇️ Co dál?
440
+
441
+ **Prosím, poskytněte nám zpětnou vazbu níže** - pomůžete nám zlepšit jak test, tak celou výuku. Zpětná vazba je anonymní a zabere jen 2 minuty. Děkujeme! 🙏
442
+ """
443
+
444
+ nav_msg = "# ✅ Test odeslán!\n\n**→ Přejděte na záložku 'Výsledky' pro zobrazení výsledků a zpětnou vazbu**"
445
+
446
+ return result, nav_msg
447
+
448
+ go.click(start, [kod,typ],
449
+ [msg,kod_s,typ_s,info,send,send_msg]+[x for g in qs for x in g])
450
 
451
+ send.click(submit, [kod_s,typ_s]+[q[3] for q in qs], [res, send_msg])
452
+
453
+ fb.click(lambda k,t,ot,st,ut,ov,sv,uv,c: (save_fb(k,t,ot,st,ut,ov,sv,uv,c), "✅ **Děkujeme za zpětnou vazbu!** Vaše připomínky jsou pro nás velmi cenné.")[1] if k else "❌ Nelze odeslat - test nebyl dokončen",
454
  [kod_s,typ_s,obt_t,sroz_t,uzit_t,obt_v,sroz_v,uzit_v,kom], fb_msg)
455
+
456
  dlr.click(lambda p: get_file(p,"r"), pwd, [dl,dlm])
457
  dlf.click(lambda p: get_file(p,"f"), pwd, [dl,dlm])
458