|
import streamlit as st |
|
import os |
|
import random |
|
import numpy as np |
|
import google.generativeai as genai |
|
|
|
|
|
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: |
|
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: |
|
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: |
|
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 |
|
|
|
|
|
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() |