import streamlit as st import os import random import numpy as np import google.generativeai as genai # Configuración de la API KEY gemini_api_key = os.getenv("GEMINI_API_KEY") if gemini_api_key is None: raise ValueError("La variable de entorno GEMINI_API_KEY no está configurada.") genai.configure(api_key=gemini_api_key) model = genai.GenerativeModel('gemini-1.5-flash-latest') def chat_with_model(user_input): """Envía una pregunta al modelo de IA y obtiene una respuesta.""" try: response = model.generate_content(user_input) return response.text except Exception as e: return f"Error al generar contenido: {e}" def tiene_solucion_unica(matriz_coeficientes, matriz_resultados): """Determina si un sistema de ecuaciones tiene solución única.""" try: np.linalg.solve(matriz_coeficientes, matriz_resultados) return True except np.linalg.LinAlgError: return False def generar_ecuacion_y_respuestas(): """Genera una ecuación lineal con una solución y tres respuestas incorrectas.""" a = random.randint(1, 10) b = random.randint(-10, 10) c = random.randint(-10, 10) x = (c - b) / a respuestas_incorrectas = set() while len(respuestas_incorrectas) < 3: respuesta_erronea = x + random.choice([-2, -1, 1, 2]) * random.random() respuestas_incorrectas.add(round(respuesta_erronea, 2)) respuestas = list(respuestas_incorrectas) + [round(x, 2)] random.shuffle(respuestas) ecuacion = f"{a}x + ({b}) = {c}" if b < 0 else f"{a}x + {b} = {c}" return ecuacion, respuestas, round(x, 2) def generar_sistema_ecuaciones_2x2_y_respuestas(): """Genera un sistema de ecuaciones lineales 2x2 con solución única y tres respuestas incorrectas.""" while True: a, b, e = random.randint(1, 10), random.randint(1, 10), random.randint(-10, 10) c, d, f = random.randint(1, 10), random.randint(1, 10), random.randint(-10, 10) if tiene_solucion_unica(np.array([[a, b], [c, d]]), np.array([e, f])): break matriz_coeficientes = np.array([[a, b], [c, d]]) matriz_resultados = np.array([e, f]) soluciones = np.linalg.solve(matriz_coeficientes, matriz_resultados) respuestas_incorrectas = {(round(soluciones[0] + random.choice([-2, -1, 1, 2]) * random.random(), 2), round(soluciones[1] + random.choice([-2, -1, 1, 2]) * random.random(), 2)) for _ in range(3)} respuestas_correctas = (round(soluciones[0], 2), round(soluciones[1], 2)) respuestas = list(respuestas_incorrectas) + [respuestas_correctas] random.shuffle(respuestas) sistema = f"{a}x + {b}y = {e}\n\n\n{c}x + {d}y = {f}" return sistema, respuestas, respuestas_correctas def generar_sistema_ecuaciones_3x3_y_respuestas(): """Genera un sistema de ecuaciones lineales 3x3 con solución única y tres respuestas incorrectas.""" while True: a, b, c, e = random.randint(1, 10), random.randint(1, 10), random.randint(1, 10), random.randint(-10, 10) d, f, g, h = random.randint(1, 10), random.randint(1, 10), random.randint(1, 10), random.randint(-10, 10) i, j, k, l = random.randint(1, 10), random.randint(1, 10), random.randint(1, 10), random.randint(-10, 10) matriz_coeficientes = np.array([[a, b, c], [d, f, g], [i, j, k]]) matriz_resultados = np.array([e, h, l]) if tiene_solucion_unica(matriz_coeficientes, matriz_resultados): break soluciones = np.linalg.solve(matriz_coeficientes, matriz_resultados) respuestas_incorrectas = {(round(soluciones[0] + random.choice([-2, -1, 1, 2]) * random.random(), 2), round(soluciones[1] + random.choice([-2, -1, 1, 2]) * random.random(), 2), round(soluciones[2] + random.choice([-2, -1, 1, 2]) * random.random(), 2)) for _ in range(3)} respuestas_correctas = (round(soluciones[0], 2), round(soluciones[1], 2), round(soluciones[2], 2)) respuestas = list(respuestas_incorrectas) + [respuestas_correctas] random.shuffle(respuestas) sistema = f"{a}x + {b}y + {c}z = {e}\n\n\n{d}x + {f}y + {g}z = {h}\n\n\n{i}x + {j}y + {k}z = {l}" return sistema, respuestas, respuestas_correctas def manejar_respuesta(problema, respuesta_elegida, respuesta_correcta, nivel): """Evalúa la respuesta del usuario, proporcionando retroalimentación y una explicación.""" tolerancia = 1e-9 correcto = False if nivel == 2: # Sistema 3x3 correcto = all(abs(e - c) < tolerancia for e, c in zip(respuesta_elegida, respuesta_correcta)) if correcto: explicacion = chat_with_model(f"Explica el sistema de ecuaciones lineales 3x3 '{problema}' y por qué la respuesta {respuesta_elegida} es correcta.") else: explicacion = chat_with_model(f"Explica el sistema de ecuaciones lineales 3x3 '{problema}' y por qué la respuesta {respuesta_elegida} es incorrecta.") elif nivel == 1: # Sistema 2x2 correcto = all(abs(e - c) < tolerancia for e, c in zip(respuesta_elegida, respuesta_correcta)) if correcto: explicacion = chat_with_model(f"Explica el sistema de ecuaciones lineales 2x2 '{problema}' y por qué la respuesta {respuesta_elegida} es correcta.") else: explicacion = chat_with_model(f"Explica el sistema de ecuaciones lineales 2x2 '{problema}' y por qué la respuesta {respuesta_elegida} es incorrecta.") else: # Ecuación lineal correcto = abs(respuesta_elegida - respuesta_correcta) < tolerancia if correcto: explicacion = chat_with_model(f"Explica la ecuación lineal '{problema}' y por qué la respuesta {respuesta_elegida} es correcta.") else: explicacion = chat_with_model(f"Explica la ecuación lineal '{problema}' y por qué la respuesta {respuesta_elegida} es incorrecta.") if correcto: resultado = "¡Correcto! +1 punto." if st.session_state.aciertos >= 5 and nivel == 0: nivel = 1 st.success("¡Felicitaciones, has pasado al nivel Intermedio: Sistemas de ecuaciones lineales 2x2!") elif st.session_state.aciertos >= 10 and nivel == 1: nivel = 2 st.success("¡Felicitaciones, has pasado al nivel Difícil: Sistemas de ecuaciones lineales 3x3!") st.session_state.aciertos += 1 else: resultado = "Incorrecto, sigue practicando." st.session_state.errores += 1 return resultado + f" Escogiste la respuesta: {respuesta_elegida}. La respuesta correcta es: {respuesta_correcta}.\n{explicacion}", nivel # Interfaz de usuario y lógica de la aplicación st.title("Desafío de Matemáticas") st.markdown("Intenta resolver el problema y selecciona tu respuesta.") if 'aciertos' not in st.session_state: st.session_state.aciertos = 0 if 'errores' not in st.session_state: st.session_state.errores = 0 if 'nivel' not in st.session_state: st.session_state.nivel = 0 if 'nuevo_problema' not in st.session_state or st.session_state.nuevo_problema: st.session_state.nuevo_problema = False if st.session_state.nivel == 2: problema_actual, respuestas, respuesta_correcta = generar_sistema_ecuaciones_3x3_y_respuestas() elif st.session_state.nivel == 1: problema_actual, respuestas, respuesta_correcta = generar_sistema_ecuaciones_2x2_y_respuestas() else: problema_actual, respuestas, respuesta_correcta = generar_ecuacion_y_respuestas() st.session_state.problema = problema_actual st.session_state.respuestas = respuestas st.session_state.respuesta_correcta = respuesta_correcta niveles = ["Principiante", "Intermedio", "Difícil"] nivel_actual = niveles[st.session_state.nivel] st.sidebar.markdown(f"Nivel: {nivel_actual}") st.sidebar.write(f"Aciertos: {st.session_state.aciertos}") st.sidebar.write(f"Errores: {st.session_state.errores}") st.write(st.session_state.problema) opciones = [f"{r[0]}, {r[1]}" if isinstance(r, tuple) else str(r) for r in st.session_state.respuestas] seleccion = st.radio("Elige tu respuesta", opciones, key="opciones") respuesta_elegida = tuple(map(float, seleccion.split(', '))) if "," in seleccion else float(seleccion) if st.button("Enviar"): resultado, nuevo_nivel = manejar_respuesta(st.session_state.problema, respuesta_elegida, st.session_state.respuesta_correcta, st.session_state.nivel) st.write(resultado) st.session_state.nivel = nuevo_nivel st.session_state.nuevo_problema = True boton_nuevo_problema = st.button("Generar Nuevo Problema") if boton_nuevo_problema: st.session_state.nuevo_problema = True st.experimental_rerun()