# streamlit_app.py import json, random, streamlit as st from pathlib import Path DATA_FILE = Path(__file__).parent / "master_evaluacion_evaluado.json" @st.cache_data def load_data(path): with open(path, encoding="utf-8") as f: return json.load(f) data = load_data(DATA_FILE) # ───────── Helpers ───────── def random_question(): return random.choice(data["preguntas"]) def random_case(): return random.choice(data["casos_clinicos"]) def build_exam(): preguntas = random.sample(data["preguntas"], 38) casos = random.sample(data["casos_clinicos"], 1) items = [{"grupo": "normal", "data": q} for q in preguntas] for c in casos: # bloques de caso completos for q in c["preguntas"]: items.append({"grupo": c["id"], "data": {**q, "caso": c["titulo"], "context": c["contexto"]}}) return items # ───────── Estado inicial ───────── if "mode" not in st.session_state: st.session_state.mode = "preguntas" # preguntas | caso | examen st.session_state.question = random_question() st.session_state.case_list = [] st.session_state.case_idx = 0 st.session_state.exam_items = [] st.session_state.exam_idx = 0 st.session_state.hits_norm = 0 st.session_state.hits_case = {} st.session_state.total_case = {} # ───────── Barra lateral ───────── st.sidebar.title("Evaluación") if st.sidebar.button("Preguntas sueltas"): st.session_state.mode = "preguntas" st.session_state.question = random_question() st.rerun() if st.sidebar.button("Casos clínicos"): st.session_state.mode = "caso" caso = random_case() st.session_state.case_list = [ {**q, "caso": caso["titulo"], "context": caso["contexto"]} for q in caso["preguntas"] ] st.session_state.case_idx = 0 st.session_state.question = st.session_state.case_list[0] st.rerun() if st.sidebar.button("Examen (38 + 1 caso)"): st.session_state.mode = "examen" st.session_state.exam_items = build_exam() st.session_state.exam_idx = 0 st.session_state.hits_norm = 0 st.session_state.hits_case.clear() st.session_state.total_case = {} for it in st.session_state.exam_items: if it["grupo"] != "normal": st.session_state.total_case[it["grupo"]] = \ st.session_state.total_case.get(it["grupo"], 0) + 1 st.session_state.question = st.session_state.exam_items[0]["data"] st.rerun() st.sidebar.markdown("---") st.sidebar.markdown("Creado con ❤️ por Requetito") # ───────── Encabezado: modo + progreso ───────── mode_label = { "preguntas": "Práctica – Preguntas sueltas", "caso": "Práctica – Casos clínicos", "examen": "Examen final" } st.subheader(mode_label[st.session_state.mode]) progreso = "" if st.session_state.mode == "examen": progreso = f"{st.session_state.exam_idx + 1} / {len(st.session_state.exam_items)}" elif st.session_state.mode == "caso": progreso = f"{st.session_state.case_idx + 1} / {len(st.session_state.case_list)}" if progreso: st.caption(progreso) # ───────── Pregunta ───────── q = st.session_state.question if "context" in q: st.info(f"**CONTEXTO ({q['caso']})**\n\n{q['context']}") st.markdown(f"### {q['pregunta']}") selected = st.radio( "Elige una respuesta:", options=list(q["opciones"].keys()), format_func=lambda k: f"{k}. {q['opciones'][k]}", index=None, key=f"radio_{q['id']}_{st.session_state.mode}" ) col1, col2 = st.columns(2) comprobar = col1.button("✅ Comprobar") siguiente = col2.button("➡️ Siguiente") # contenedores feedback feedback_box = st.empty() justif_box = st.empty() # ───────── Comprobar ───────── if comprobar and selected: correcta = q["respuesta_correcta"] ok = selected == correcta if ok: feedback_box.success("✅ ¡Correcto!") else: feedback_box.error(f"❌ Incorrecto. La respuesta correcta era **{correcta}**.") justif_box.markdown(f"**Justificación:**\n{q['justificacion']}") if st.session_state.mode == "examen": grp = st.session_state.exam_items[st.session_state.exam_idx]["grupo"] if grp == "normal" and ok: st.session_state.hits_norm += 1 elif grp != "normal" and ok: st.session_state.hits_case[grp] = \ st.session_state.hits_case.get(grp, 0) + 1 # ───────── Siguiente ───────── if siguiente: feedback_box.empty(); justif_box.empty() # limpiar if st.session_state.mode == "preguntas": st.session_state.question = random_question() elif st.session_state.mode == "caso": st.session_state.case_idx += 1 if st.session_state.case_idx == len(st.session_state.case_list): caso = random_case() st.session_state.case_list = [ {**q, "caso": caso["titulo"], "context": caso["contexto"]} for q in caso["preguntas"] ] st.session_state.case_idx = 0 st.session_state.question = st.session_state.case_list[st.session_state.case_idx] elif st.session_state.mode == "examen": st.session_state.exam_idx += 1 if st.session_state.exam_idx == len(st.session_state.exam_items): # Fin examen # NUEVA PONDERACIÓN pts_preg = st.session_state.hits_norm * (12.8 / 38) pts_casos = 0 detalles = [] for cid, tot in st.session_state.total_case.items(): peso_por_preg = 3.2 / tot # Caso clínico completo vale 3.2 puntos aciertos = st.session_state.hits_case.get(cid, 0) pts = aciertos * peso_por_preg pts_casos += pts detalles.append(f"{cid}: {pts:.2f} / 3.2") total = pts_preg + pts_casos aprobado = total >= 7.5 st.balloons() st.markdown( f"## 🏁 Examen finalizado\n\n" f"**Preguntas (máx 12.8):** {pts_preg:.2f}\n\n" + "\n".join(detalles) + f"\n\n**TOTAL:** {total:.2f} / 16 → " + ("✅ Aprobado" if total >= 7.5 else "❌ No aprobado") ) st.stop() st.session_state.question = \ st.session_state.exam_items[st.session_state.exam_idx]["data"] st.rerun()