En esta semana uniremos a los dos grupos (Civil por un lado, Agrícola y Agroindustrial por el otro). La metodología será la misma para todos: aprender la Arquitectura de Software necesaria para tomar un código matemático (Backend) y conectarlo con una interfaz web (Frontend).

A continuación, tienes el cuaderno de la Semana 14 completamente limpio y listo para Google Colab, con plantillas base para que cada especialidad comience a armar su Proyecto Final:


Celda 1: Texto (Markdown)

# SEMANA 14: Arquitectura del Proyecto Final (Integración Web)

**Asignatura:** Programación de Computadores con Python
**Programas:** Ingeniería Agrícola, Civil y Agroindustrial

Durante las últimas dos semanas construimos el "motor" de nuestras aplicaciones: funciones para calcular el secado de alimentos y algoritmos para resolver vigas isostáticas. Sin embargo, un motor no sirve de mucho sin un volante y un tablero de control.

Esta semana aprenderemos la **Arquitectura de Software** básica para integrar nuestra lógica matemática (Backend) con una interfaz gráfica web usando Streamlit (Frontend). Este es el primer paso oficial de su Proyecto Final.

**Objetivos de Aprendizaje:**
* Comprender la separación entre la lógica de cálculo y la interfaz de usuario.
* Estructurar un archivo de Python combinando funciones personalizadas y comandos de Streamlit.
* Diseñar un flujo de trabajo de tres pasos: Entradas de usuario $\rightarrow$ Ejecución de funciones $\rightarrow$ Despliegue de resultados.

Celda 2: Texto (Markdown)

## SESIÓN 1: La Estructura de una Aplicación Profesional

Una aplicación web bien diseñada nunca mezcla todo el código de forma desordenada. Siempre sigue una estructura clara de "bloques":

1. **Importación de Librerías:** Traer las herramientas (`streamlit`, `sympy`, `math`, etc.).
2. **El "Cerebro" (Funciones de Cálculo):** Aquí pegamos las funciones que creamos en las Semanas 12 y 13. Estas funciones no imprimen nada en pantalla (`print`), solo procesan datos y los devuelven (`return`).
3. **El "Rostro" (Interfaz Streamlit):** Títulos, textos y configuración visual.
4. **El Panel de Control (Entradas):** Los `st.number_input` donde el usuario digita los datos.
5. **El Botón de Acción y los Resultados (Salidas):** El bloque `if st.button():` que toma los datos del panel, llama al cerebro para calcular, y muestra el resultado con `st.success` o gráficas.

A continuación, elige y ejecuta **SOLO LA CELDA** que corresponde a tu carrera para generar el archivo base de tu proyecto.

Celda 3: Código (Python)

%%writefile app_civil.py
# ==========================================
# PLANTILLA RUTA A: INGENIERÍA CIVIL (VIGAS)
# ==========================================
import streamlit as st
import sympy as sp
from sympy.physics.continuum_mechanics import Beam

# --- 1. EL CEREBRO (Funciones Lógicas) ---
def resolver_viga_simple(longitud, carga_distribuida):
    E, I = sp.symbols('E I')
    viga = Beam(longitud, E, I)
    R_A, R_B = sp.symbols('R_A R_B')
    
    # Aplicamos apoyos y carga
    viga.apply_load(R_A, 0, -1)
    viga.apply_load(R_B, longitud, -1)
    viga.apply_load(-carga_distribuida, 0, 0, end=longitud)
    
    viga.bc_deflection = [(0, 0), (longitud, 0)]
    viga.solve_for_reaction_loads(R_A, R_B)
    
    return viga.reaction_loads[R_A], viga.reaction_loads[R_B]

# --- 2. EL ROSTRO (Interfaz Gráfica) ---
st.title("🏗️ Calculadora Estructural de Vigas")
st.write("Análisis de reacciones para vigas isostáticas con carga distribuida.")

# --- 3. PANEL DE CONTROL (Entradas) ---
st.sidebar.header("Parámetros de Diseño")
L = st.sidebar.number_input("Longitud de la viga (m):", min_value=1.0, value=5.0)
q = st.sidebar.number_input("Carga distribuida (kN/m):", min_value=0.0, value=10.0)

# --- 4. ACCIÓN Y RESULTADOS ---
if st.button("Calcular Reacciones"):
    # Llamamos al cerebro
    reaccion_A, reaccion_B = resolver_viga_simple(L, q)
    
    # Mostramos resultados
    st.success("Cálculo completado con éxito.")
    col1, col2 = st.columns(2)
    col1.metric(label="Reacción en Apoyo A (kN)", value=float(reaccion_A))
    col2.metric(label="Reacción en Apoyo B (kN)", value=float(reaccion_B))
    
    st.info("Nota para el Proyecto Final: Aquí integraremos las gráficas de Cortante y Momento.")

Celda 4: Código (Python)

%%writefile app_agro.py
# ==============================================================
# PLANTILLA RUTA B: INGENIERÍA AGRÍCOLA / AGROINDUSTRIAL (SECADO)
# ==============================================================
import streamlit as st

# --- 1. EL CEREBRO (Funciones Lógicas) ---
def agua_a_evaporar(m_i, M_i, M_f):
    return m_i * ((M_i - M_f) / (100 - M_f))

def calcular_caudal(calor_kJ, t_amb, t_col):
    return calor_kJ / (1.006 * (t_col - t_amb) * 1.2) # Volumen en m3

# --- 2. EL ROSTRO (Interfaz Gráfica) ---
st.title("☀️ Simulador de Secador Solar")
st.write("Dimensionamiento termodinámico para deshidratación de productos agrícolas.")

# --- 3. PANEL DE CONTROL (Entradas) ---
st.sidebar.header("Datos del Producto")
masa_inicial = st.sidebar.number_input("Masa de producto fresco (kg):", min_value=1.0, value=100.0)
hum_inicial = st.sidebar.slider("Humedad inicial (% wb):", 10.0, 95.0, 80.0)
hum_final = st.sidebar.slider("Humedad final deseada (% wb):", 5.0, 50.0, 12.0)

st.sidebar.header("Datos Ambientales")
temp_amb = st.sidebar.number_input("Temp. Ambiente (°C):", value=30.0)
temp_col = st.sidebar.number_input("Temp. Colector (°C):", value=60.0)

# --- 4. ACCIÓN Y RESULTADOS ---
if st.button("Ejecutar Simulación Termodinámica"):
    if temp_col <= temp_amb:
        st.error("La temperatura del colector debe ser mayor a la ambiente.")
    else:
        # Llamamos al cerebro
        agua_remover = agua_a_evaporar(masa_inicial, hum_inicial, hum_final)
        energia_kJ = agua_remover * 2260.0
        volumen_aire = calcular_caudal(energia_kJ, temp_amb, temp_col)
        
        # Mostramos resultados
        st.success("Balance de masa y energía completado.")
        st.metric(label="Agua a evaporar (kg)", value=f"{agua_remover:.2f}")
        st.metric(label="Energía térmica requerida (kJ)", value=f"{energia_kJ:.2f}")
        st.metric(label="Volumen de aire necesario (m³)", value=f"{volumen_aire:.2f}")

Celda 5: Texto (Markdown)

## SESIÓN 2: Prueba en Vivo del Proyecto Base

Ahora que has generado el archivo de tu especialidad, vamos a abrir un túnel para visualizar cómo quedó estructurada la aplicación web.

**Instrucciones:**
1. Ejecuta la celda de abajo.
2. Copia la contraseña IP.
3. Abre el enlace de `localtunnel`.
4. Interactúa con la barra lateral izquierda (`sidebar`) que acabamos de crear para cambiar los valores, y presiona el botón principal para ver cómo responde el "cerebro" matemático.

Celda 6: Código (Python)

import urllib
# Obtenemos la IP para usarla como contraseña
password = urllib.request.urlopen('https://ipv4.icanhazip.com').read().decode('utf8').strip()
print("-------------------------------------------------------------")
print(f"🔑 COPIA ESTA CONTRASEÑA ANTES DE ABRIR EL ENLACE: {password}")
print("-------------------------------------------------------------")

# Instalamos herramientas (incluimos sympy por si acaso)
!pip install streamlit sympy -q
!npm install localtunnel -g &> /dev/null

# === IMPORTANTE === 
# Si eres de Civil, deja la línea como '!streamlit run app_civil.py'
# Si eres de Agro/Agrícola, cambia la línea a '!streamlit run app_agro.py'
!streamlit run app_civil.py &> /dev/null &

# Creamos el túnel
!npx localtunnel --port 8501

Celda 7: Texto (Markdown)

---
### Interacción con el Tutor IA 🤖

La arquitectura de una aplicación es como los planos de un edificio. Pídele a tu asistente que te ayude a planear la mejora visual de tu proyecto:

> **PROMPT DE APRENDIZAJE - SEMANA 14:**
> Actúa como un Diseñador de Interfaces de Usuario (UI/UX) especializado en software de ingeniería. Estoy armando la estructura en Streamlit de mi proyecto final universitario.
> 1) Explícame por qué es una buena práctica de programación separar las funciones matemáticas complejas (backend) de los comandos visuales (frontend).
> 2) En el código usamos `st.sidebar` para poner los controles a la izquierda. ¿Qué ventajas tiene esto para la experiencia del usuario que usará mi calculadora?
> 3) Mi aplicación mostrará varios resultados numéricos clave. ¿Qué elementos visuales de Streamlit me recomiendas para que los resultados no se vean como simple texto aburrido? (Háblame de `st.metric` o `st.columns`).
> Después hazme 2 preguntas sobre cómo pienso organizar visualmente mi proyecto final.

Celda 8: Texto (Markdown)

---
## ACTIVIDAD FINAL: Hoja "Estudia y Aprende"

Prepara la arquitectura de tu proyecto en papel:

> **PROMPT GLOBAL DE CIERRE:**
> Actúa como tutor experto en Arquitectura de Software. Elabora un RESUMEN BREVE que cumpla estas condiciones:
> 1. Debe caber en UNA SOLA HOJA escrita a mano.
> 2. Lenguaje claro y técnico.
> 3. Debe incluir: El concepto de separación entre Frontend y Backend en una app, para qué sirve la barra lateral (`st.sidebar`), y el flujo correcto de ejecución al presionar un botón.
> 4. Pensado para que yo lo escriba comprendiendo lo esencial.
> Al final agrega una frase motivadora sobre el inicio del desarrollo de su proyecto final integrador.

**Instrucción para el estudiante:** En el reverso de tu hoja, dibuja el boceto final o "Wireframe" de cómo quieres que se vea tu aplicación web de ingeniería cuando esté terminada en la Semana 16. Señala dónde irán las entradas, dónde los resultados y dónde planeas ubicar las gráficas.

Con esto, los estudiantes ya tienen la base exacta sobre la cual trabajar. A partir de aquí, el proceso se vuelve altamente creativo y de taller.

Para la Semana 15, mi sugerencia es que el enfoque del cuaderno (y de la clase) sea estrictamente el Taller de Integración Gráfica en VSCode: es decir, cómo pasar este boceto de Colab a sus computadores personales, cómo conectar Matplotlib/Sympy para que las gráficas salgan en la web (usando st.pyplot), y cómo preparar el terreno para que en la Semana 16 solo tengan que hacer el git push a Streamlit Community Cloud para su sustentación.