Guía Maestra del Curso: La siguiente estrategia, es iniciar con un problema concreto y relevante para cada Ingeniería con el objeto de captar el interés y dar un “porqué” inmediato para aprender los conceptos de programación.

A continuación, se detalla el plan de trabajo para cada semana del curso.

Semana 1: Variables, Entrada y Salida de Datos

El objetivo de esta semana es aprender a comunicarnos con el computador: cómo darle información (entrada), cómo pedirle que la guarde en “cajas” con nombre (variables) y cómo nos puede mostrar los resultados (salida).

Situaciones de Interés para Iniciar la Semana

Al comenzar la clase, presentaremos tres escenarios, uno para cada ingeniería. El reto para los estudiantes será pensar en cómo darían instrucciones precisas a un computador para resolverlos.

  1. Situación de Interés en Ingeniería Agrícola 🌾: Un agricultor necesita saber cuántos kilogramos de semilla de maíz debe comprar para sembrar un lote rectangular. Conoce la densidad de siembra recomendada (kg por hectárea) y las dimensiones del lote (largo y ancho en metros).

  2. Situación de Interés en Ingeniería Agroindustrial 🥭: En una planta de procesamiento de mango, se quiere calcular el rendimiento de un lote de fruta. Se necesita un programa simple que tome el peso inicial de los mangos antes de pelarlos y deshuesarlos, y el peso final de la pulpa obtenida, para expresar el rendimiento como un porcentaje.

  3. Situación de Interés en Ingeniería Civil 🧱: Un ingeniero residente de obra necesita calcular rápidamente el volumen de concreto necesario para vaciar una losa de piso rectangular simple. Debe poder ingresar el largo, el ancho y el espesor de la losa para obtener el volumen en metros cúbicos.

Resolución de Situaciones y Guía de Estudio

Una vez planteados los problemas, se introducen los conceptos de la semana (variables, input(), print(), float()) como las herramientas necesarias. A continuación, se muestra cómo aplicarlas para resolver cada caso.

1. Caso de Ingeniería Agrícola: Cálculo de Semillas

  • Paso a Paso del Código:

    1. Saludar al usuario y explicar qué hace el programa.
    2. Pedir al usuario que ingrese el largo del lote en metros (input).
    3. Pedir el ancho del lote en metros (input).
    4. Pedir la densidad de siembra en kg/hectárea (input).
    5. Convertir las entradas de texto a números decimales (float).
    6. Calcular el área en metros cuadrados (largo * ancho).
    7. Convertir el área a hectáreas (1 hectárea = 10,000 m²).
    8. Calcular la cantidad total de semilla (área en hectáreas * densidad).
    9. Mostrar el resultado final al usuario de forma clara (print).
  • Código de Ejemplo en Colab:

    # --- CALCULADORA DE SEMILLAS PARA LOTE AGRÍCOLA ---
    
    print("🌱 Bienvenido a la Calculadora de Semillas de Maíz")
    
    # Paso 2, 3 y 4: Pedir los datos al usuario
    largo_str = input("Ingrese el largo del lote (en metros): ")
    ancho_str = input("Ingrese el ancho del lote (en metros): ")
    densidad_str = input("Ingrese la densidad de siembra (en kg por hectárea): ")
    
    # Paso 5: Convertir los textos a números decimales
    largo_m = float(largo_str)
    ancho_m = float(ancho_str)
    densidad_kg_ha = float(densidad_str)
    
    # Paso 6 y 7: Calcular el área y convertir a hectáreas
    area_m2 = largo_m * ancho_m
    area_ha = area_m2 / 10000
    
    # Paso 8: Calcular la cantidad de semilla
    semilla_total_kg = area_ha * densidad_kg_ha
    
    # Paso 9: Mostrar el resultado
    print("\n--- RESULTADO DEL CÁLCULO ---")
    print(f"El área del lote es de {area_ha:.4f} hectáreas.")
    print(f"Necesitará comprar {semilla_total_kg:.2f} kg de semilla de maíz.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es una variable en Python y para qué sirve? Dame una analogía.", "¿Por qué la función input() siempre devuelve texto (string) y cómo puedo convertir ese texto en un número?"
    • Estructura del Código: "Escribe el esqueleto de un programa en Python que pida dos números, los multiplique y muestre el resultado."
    • Resolución Guiada: "Necesito calcular la cantidad de semilla para un lote. Primero debo calcular el área en m² (largo * ancho) y luego convertirla a hectáreas. ¿Cómo convierto metros cuadrados a hectáreas en Python?"
    • Formato de Salida: "En mi código de Python, ¿cómo puedo hacer que un número decimal se muestre con solo dos decimales al usar la función print()?"

2. Caso de Ingeniería Agroindustrial: Cálculo de Rendimiento

  • Paso a Paso del Código:

    1. Explicar el propósito de la calculadora.
    2. Pedir el peso inicial del lote de mangos en kg (input).
    3. Pedir el peso final de la pulpa obtenida en kg (input).
    4. Convertir ambos pesos a números decimales (float).
    5. Calcular el rendimiento usando la fórmula: (peso_final / peso_inicial) * 100.
    6. Mostrar el resultado del rendimiento, formateado como porcentaje.
  • Código de Ejemplo en Colab:

    # --- CALCULADORA DE RENDIMIENTO AGROINDUSTRIAL ---
    
    print("🥭 Bienvenido a la Calculadora de Rendimiento de Pulpa")
    
    # Paso 2 y 3: Pedir los datos al usuario
    peso_inicial_str = input("Ingrese el peso inicial del lote de mangos (en kg): ")
    peso_final_str = input("Ingrese el peso final de la pulpa obtenida (en kg): ")
    
    # Paso 4: Convertir a números
    peso_inicial = float(peso_inicial_str)
    peso_final = float(peso_final_str)
    
    # Paso 5: Calcular el rendimiento
    # Se añade una verificación para evitar división por cero
    if peso_inicial > 0:
      rendimiento_porcentaje = (peso_final / peso_inicial) * 100
      # Paso 6: Mostrar el resultado
      print("\n--- RESULTADO DEL ANÁLISIS ---")
      print(f"El rendimiento del lote fue del {rendimiento_porcentaje:.2f}%.")
    else:
      print("Error: El peso inicial debe ser mayor que cero.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué son los operadores aritméticos en Python? Dame una lista.", "¿Por qué es importante verificar que no estoy dividiendo por cero en un programa?"
    • Estructura del Código: "Quiero crear un programa que calcule un porcentaje. Necesito pedir un valor total y un valor parcial. ¿Cómo estructuro el código en Python?"
    • Resolución Guiada: "Tengo dos variables, 'peso_inicial' y 'peso_final'. Escribe la fórmula en Python para calcular el rendimiento porcentual."

3. Caso de Ingeniería Civil: Cálculo de Volumen de Concreto

  • Paso a Paso del Código:

    1. Presentar la herramienta al usuario.
    2. Solicitar el largo, ancho y espesor de la losa, todos en metros (input).
    3. Convertir todas las entradas a números decimales (float).
    4. Calcular el volumen multiplicando las tres dimensiones.
    5. Presentar el volumen calculado en metros cúbicos.
  • Código de Ejemplo en Colab:

    # --- CALCULADORA DE VOLUMEN DE CONCRETO PARA LOSA ---
    
    print("🧱 Bienvenido a la Calculadora de Volumen de Concreto")
    
    # Paso 2: Pedir las dimensiones
    largo_str = input("Ingrese el largo de la losa (en metros): ")
    ancho_str = input("Ingrese el ancho de la losa (en metros): ")
    espesor_str = input("Ingrese el espesor de la losa (en metros): ")
    
    # Paso 3: Convertir a números
    largo = float(largo_str)
    ancho = float(ancho_str)
    espesor = float(espesor_str)
    
    # Paso 4: Calcular el volumen
    volumen_m3 = largo * ancho * espesor
    
    # Paso 5: Mostrar el resultado
    print("\n--- RESULTADO DEL CÁLCULO ---")
    print(f"El volumen de concreto necesario es de {volumen_m3:.3f} metros cúbicos.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Python sigue el orden de las operaciones matemáticas (PEMDAS)? Dame un ejemplo."
    • Estructura del Código: "Necesito un programa que pida 3 números al usuario, los multiplique entre sí y muestre el resultado. ¿Puedes escribírmelo en Python?"
    • Resolución Guiada: "Tengo 3 variables en Python: 'largo', 'ancho' y 'espesor'. ¿Cuál es la línea de código para calcular el 'volumen'?", "¿Cómo puedo mostrar 'm³' en la salida de mi programa de Python?"

Semanas 2 y 3: Tomando Decisiones y Repitiendo Tareas (11 - 22 de agosto)

El objetivo de estas dos semanas es darles a nuestros programas la capacidad de “pensar”. Aprenderemos las estructuras de control que les permiten tomar decisiones basadas en condiciones (if/elif/else) y ejecutar tareas de forma repetitiva (for, while), que es la base de toda automatización.

Situaciones de Interés para Iniciar

  1. Situación de Interés en Ingeniería Agrícola 💧: Se está diseñando el software para un sistema de riego “inteligente”. El programa debe leer el nivel de humedad actual del suelo (un valor de 0 a 100) y decidir qué acción tomar: no hacer nada, aplicar un riego ligero o aplicar un riego profundo, según umbrales predefinidos.

  2. Situación de Interés en Ingeniería Agroindustrial 📦: En una línea de empaque de frutas, un sensor mide el peso de cada fruta. Se necesita un programa que analice una lista de pesos de un lote y cuente cuántas frutas cumplen con el estándar de “Exportación” (ej. > 250g), cuántas son de “Mercado Nacional” (entre 150g y 250g) y cuántas se consideran “Rechazo” (< 150g).

  3. Situación de Interés en Ingeniería Civil 🔩: Durante el control de calidad en una obra, se deben realizar pruebas de resistencia a la compresión en múltiples muestras de concreto. Se requiere un programa que permita al usuario ingresar el resultado de cada prueba (en PSI) y verifique si cumple con el mínimo requerido por el diseño. El programa debe poder analizar una muestra tras otra, hasta que el usuario decida detenerse.

Resolución de Situaciones y Guía de Estudio

A continuación, se muestra cómo resolver cada escenario usando las estructuras de control de Python.

1. Caso de Ingeniería Agrícola: Lógica de Riego Inteligente (if/elif/else)

  • Paso a Paso del Código:

    1. Definir los umbrales de humedad (ej. por debajo de 30% es seco, entre 30% y 70% es óptimo, por encima de 70% es saturado).
    2. Pedir al usuario el nivel de humedad actual.
    3. Convertir la entrada a un número (float).
    4. Usar una estructura if/elif/else para comparar la humedad con los umbrales.
    5. if la humedad es muy alta, imprimir “Suelo saturado, no regar”.
    6. elif la humedad es muy baja, imprimir “Suelo seco, aplicando riego profundo”.
    7. else (para el caso intermedio), imprimir “Humedad óptima, aplicando riego ligero de mantenimiento”.
  • Código de Ejemplo en Colab:

    # --- SOFTWARE PARA SISTEMA DE RIEGO INTELIGENTE ---
    
    print("💧 Módulo de Decisión de Riego")
    
    # Pedir el dato del sensor (simulado con input)
    humedad_str = input("Ingrese el porcentaje de humedad del suelo (0-100): ")
    humedad = float(humedad_str)
    
    # Definir umbrales
    UMBRAL_OPTIMO = 30
    UMBRAL_SATURADO = 70
    
    print("\n--- ANÁLISIS Y ACCIÓN ---")
    # Estructura de decisión
    if humedad > UMBRAL_SATURADO:
      print(f"🔴 Acción: No regar. Humedad actual ({humedad}%) por encima del umbral de saturación.")
    elif humedad < UMBRAL_OPTIMO:
      print(f"🔵 Acción: Aplicar RIEGO PROFUNDO. Humedad actual ({humedad}%) por debajo del umbral óptimo.")
    else: # Si no es ninguna de las anteriores, está en el rango óptimo
      print(f"🟢 Acción: Aplicar RIEGO LIGERO. Humedad ({humedad}%) en niveles óptimos.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "Explícame la diferencia entre 'if', 'elif' y 'else' en Python. ¿Puedo usar múltiples 'elif'?"
    • Estructura del Código: "Escribe un programa en Python que pida una calificación numérica y la convierta a una letra (A, B, C, F) usando condicionales."
    • Resolución Guiada: "Necesito un código que haga una cosa si una variable 'x' es menor que 10, otra cosa si está entre 10 y 50, y una tercera cosa si es mayor que 50. ¿Cómo escribo esa estructura if/elif/else?"

2. Caso de Ingeniería Agroindustrial: Clasificación de Lote (for loop)

  • Paso a Paso del Código:

    1. Definir una lista con los pesos de las frutas del lote (para simular los datos del sensor).
    2. Inicializar tres contadores en cero: exportacion, nacional y rechazo.
    3. Usar un bucle for para recorrer cada peso en la lista de pesos_lote.
    4. Dentro del bucle, usar if/elif/else para clasificar cada peso.
    5. Incrementar el contador correspondiente en 1 según la clasificación.
    6. Después de que el bucle termine, imprimir los totales de cada categoría.
  • Código de Ejemplo en Colab:

    # --- SISTEMA DE CLASIFICACIÓN DE FRUTAS POR PESO ---
    
    print("📦 Analizador de Lote de Frutas")
    
    # 1. Simulación de datos del sensor
    pesos_lote = [260.5, 140.2, 180.9, 290.0, 310.1, 150.0, 250.1, 130.8, 200.0]
    
    # 2. Inicializar contadores
    contador_exportacion = 0
    contador_nacional = 0
    contador_rechazo = 0
    
    # 3. Bucle 'for' para analizar cada fruta
    for peso in pesos_lote:
      # 4. Clasificación dentro del bucle
      if peso > 250:
        contador_exportacion += 1
      elif peso >= 150: # No es necesario poner 'and peso <= 250' porque el primer 'if' ya lo descarta
        contador_nacional += 1
      else:
        contador_rechazo += 1
    
    # 6. Imprimir el resumen final
    print("\n--- RESUMEN DEL LOTE ---")
    print(f"Frutas de Exportación (>250g): \t{contador_exportacion} unidades")
    print(f"Frutas de Mercado Nacional (150-250g): \t{contador_nacional} unidades")
    print(f"Frutas de Rechazo (<150g): \t\t{contador_rechazo} unidades")
    print("---------------------------------")
    print(f"Total de frutas analizadas: \t{len(pesos_lote)} unidades")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es un bucle 'for' en Python y para qué se usa principalmente? Dame un ejemplo con una lista de nombres."
    • Estructura del Código: "Escribe un programa en Python que recorra una lista de números y cuente cuántos son pares y cuántos son impares."
    • Resolución Guiada: "Tengo una lista de números llamada 'datos'. Quiero recorrerla con un bucle 'for'. Dentro del bucle, si el número es mayor a 100, quiero sumarle 1 a una variable llamada 'contador'. ¿Cómo escribo ese código?"

3. Caso de Ingeniería Civil: Pruebas de Resistencia (while loop)

  • Paso a Paso del Código:

    1. Definir la resistencia mínima requerida.
    2. Iniciar un bucle infinito con while True:. Este tipo de bucle seguirá ejecutándose hasta que le demos una instrucción explícita para detenerse (break).
    3. Dentro del bucle, pedir al usuario que ingrese el resultado de la prueba en PSI.
    4. Verificar si el usuario escribió “salir” para terminar el programa. Si es así, usar break para salir del bucle.
    5. Si no, convertir la entrada a un número (float) y compararlo con la resistencia mínima.
    6. Imprimir si la muestra “Cumple” o “No Cumple”.
    7. Al salir del bucle, imprimir un mensaje de despedida.
  • Código de Ejemplo en Colab:

    # --- VERIFICADOR DE PRUEBAS DE RESISTENCIA DE CONCRETO ---
    
    print("🔩 Verificador de Resistencia a la Compresión")
    print("(Escribe 'salir' en cualquier momento para terminar)")
    
    # 1. Resistencia mínima requerida por el diseño
    RESISTENCIA_MINIMA_PSI = 3000
    
    # 2. Bucle 'while' para analizar muestras continuamente
    while True:
      # 3. Pedir el resultado
      resultado_str = input("\nIngrese el resultado de la prueba (en PSI): ")
    
      # 4. Condición de salida
      if resultado_str.lower() == "salir":
        break # Detiene el bucle while
    
      # 5. Convertir y evaluar
      try:
        resultado_psi = float(resultado_str)
        if resultado_psi >= RESISTENCIA_MINIMA_PSI:
          print(f"✅ Resultado: {resultado_psi} PSI. ¡CUMPLE con el estándar de {RESISTENCIA_MINIMA_PSI} PSI!")
        else:
          print(f"❌ Resultado: {resultado_psi} PSI. ¡NO CUMPLE! La muestra es rechazada.")
      except ValueError:
        print("Entrada no válida. Por favor, ingrese un número o la palabra 'salir'.")
    
    # 7. Mensaje final
    print("\n--- Proceso de verificación finalizado. ---")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Cuál es la diferencia entre un bucle 'for' y un bucle 'while'? Dame un ejemplo donde sea mejor usar 'while'.", "¿Qué hace la palabra clave 'break' dentro de un bucle?"
    • Estructura del Código: "Escribe un programa que sea una calculadora simple (suma, resta). Debe permitir al usuario hacer múltiples cálculos hasta que decida salir. ¿Qué tipo de bucle debería usar?"

Continúamos con la planificación detallada para las Semanas 4 y 5, enfocadas en cómo organizar la información de manera eficiente y cómo crear bloques de código reutilizables.

Semanas 4 y 5: Organizando la Información y Creando “Recetas” de Código (25 de agosto - 5 de septiembre)

El objetivo de estas semanas es dar un salto cualitativo en nuestra capacidad de programación. Dejaremos de trabajar con datos sueltos para aprender a agruparlos en colecciones estructuradas (Listas y Diccionarios). Además, aprenderemos a encapsular nuestra lógica en “recetas” reutilizables llamadas Funciones, lo que nos permitirá escribir código mucho más limpio, eficiente y fácil de entender.

Situaciones de Interés para Iniciar

  1. Situación de Interés en Ingeniería Agrícola 🌱: Un agrónomo consultor necesita una herramienta rápida para aconsejar a los agricultores sobre qué cultivos sembrar. Se requiere un programa que almacene información de varios cultivos (nombre, mes ideal de siembra, necesidad de agua) y que, al ingresar el nombre de un mes, recomiende qué cultivos son adecuados para sembrar en ese período.

  2. Situación de Interés en Ingeniería Agroindustrial 🏭: El jefe de bodega de una planta de alimentos necesita un sistema simple para gestionar el inventario de materia prima. El programa debe permitirle ver el stock actual, registrar la llegada de un nuevo lote de un producto (añadir al stock) y registrar el consumo de materia prima para la producción (restar del stock).

  3. Situación de Interés en Ingeniería Civil ⚖️: Un ingeniero estructural necesita calcular el peso de diferentes elementos de una construcción (vigas, columnas). El programa debe tener una base de datos con las densidades de materiales comunes (acero, concreto, madera) y, a partir del tipo de material y el volumen del elemento, debe calcular su peso total.

Resolución de Situaciones y Guía de Estudio

A continuación, la aplicación de listas, diccionarios y funciones para resolver cada escenario.

1. Caso de Ingeniería Agrícola: Planificador de Cultivos (Listas y Funciones)

  • Paso a Paso del Código:

    1. Crear una lista donde cada elemento sea un diccionario. Cada diccionario representará un cultivo y tendrá claves como nombre, mes_siembra y riego.
    2. Crear una función llamada recomendar_cultivos. Esta función recibirá dos parámetros: la lista completa de cultivos y el mes actual.
    3. Dentro de la función, usar un bucle for para recorrer la lista de cultivos.
    4. En cada iteración, usar un if para comprobar si el mes_siembra del cultivo coincide con el mes proporcionado.
    5. Si coinciden, añadir el nombre del cultivo a una nueva lista de recomendados.
    6. Al final, la función debe devolver la lista de cultivos recomendados.
    7. En el programa principal, pedir al usuario el mes y llamar a la función para obtener e imprimir las recomendaciones.
  • Código de Ejemplo en Colab:

    # --- PLANIFICADOR INTELIGENTE DE CULTIVOS ---
    
    # 1. Base de datos de cultivos (una lista de diccionarios)
    DB_CULTIVOS = [
        {"nombre": "Maíz", "mes_siembra": "Abril", "riego": "Alto"},
        {"nombre": "Frijol", "mes_siembra": "Mayo", "riego": "Medio"},
        {"nombre": "Tomate", "mes_siembra": "Abril", "riego": "Alto"},
        {"nombre": "Yuca", "mes_siembra": "Septiembre", "riego": "Bajo"},
        {"nombre": "Sorgo", "mes_siembra": "Mayo", "riego": "Bajo"}
    ]
    
    # 2. Función para obtener recomendaciones
    def recomendar_cultivos(catalogo, mes_actual):
      """Filtra el catálogo de cultivos y devuelve los recomendados para un mes."""
      cultivos_recomendados = [] # 5. Inicia una lista vacía
      for cultivo in catalogo: # 3. Recorre la base de datos
        if cultivo["mes_siembra"].lower() == mes_actual.lower(): # 4. Compara
          cultivos_recomendados.append(cultivo["nombre"]) # 5. Añade si coincide
      return cultivos_recomendados # 6. Devuelve la lista final
    
    # 7. Programa Principal
    print("🌱 Bienvenido al Asistente de Siembra")
    mes_usuario = input("Ingrese el mes actual (ej. Abril): ")
    
    recomendaciones = recomendar_cultivos(DB_CULTIVOS, mes_usuario)
    
    print("\n--- RECOMENDACIONES ---")
    if recomendaciones: # Si la lista no está vacía
      print(f"Para el mes de {mes_usuario}, se recomienda sembrar:")
      for cultivo in recomendaciones:
        print(f"- {cultivo}")
    else:
      print(f"No se encontraron cultivos ideales para sembrar en {mes_usuario}.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es un diccionario en Python y cómo se diferencia de una lista?", "Explícame el propósito de la palabra clave 'return' en una función de Python."
    • Estructura del Código: "Escribe una función en Python que reciba una lista de nombres y una letra, y devuelva una nueva lista solo con los nombres que empiezan con esa letra."
    • Resolución Guiada: "Tengo una lista de diccionarios. Cada diccionario tiene una clave 'ciudad'. ¿Cómo escribo un bucle 'for' para imprimir solo el valor de la clave 'ciudad' de cada diccionario en la lista?"

2. Caso de Ingeniería Agroindustrial: Gestión de Inventario (Diccionarios y Funciones)

  • Paso a Paso del Código:

    1. Crear un diccionario para representar el inventario. Las claves serán los nombres de los productos y los valores serán las cantidades en stock.
    2. Crear una función agregar_stock que reciba el inventario, el nombre del ítem y la cantidad a añadir. La función modificará el diccionario.
    3. Crear una función usar_stock que reciba el inventario, el ítem y la cantidad a usar. Esta función debe verificar si hay suficiente stock antes de restar.
    4. Crear una función mostrar_inventario que recorra el diccionario e imprima el stock de cada producto.
    5. En el programa principal, usar un bucle while para mostrar un menú de opciones al usuario (ver, agregar, usar, salir) y llamar a la función correspondiente según su elección.
  • Código de Ejemplo en Colab:

    # --- SISTEMA BÁSICO DE GESTIÓN DE INVENTARIO ---
    
    # 1. El inventario es un diccionario
    inventario = {"Harina (kg)": 500, "Azúcar (kg)": 250, "Sal (kg)": 100}
    
    # 2. Función para añadir stock
    def agregar_stock(inv, item, cantidad):
      if item in inv:
        inv[item] += cantidad
      else:
        inv[item] = cantidad
      print(f"✅ Se agregaron {cantidad} a '{item}'. Nuevo total: {inv[item]}")
    
    # 3. Función para usar stock
    def usar_stock(inv, item, cantidad):
      if item in inv and inv[item] >= cantidad:
        inv[item] -= cantidad
        print(f"✅ Se usaron {cantidad} de '{item}'. Quedan: {inv[item]}")
      else:
        print(f"❌ Error: No hay suficiente stock de '{item}' o el ítem no existe.")
    
    # 4. Función para mostrar el inventario
    def mostrar_inventario(inv):
      print("\n--- INVENTARIO ACTUAL ---")
      for item, cantidad in inv.items():
        print(f"- {item}: {cantidad}")
      print("-------------------------")
    
    # 5. Programa principal con menú
    while True:
      mostrar_inventario(inventario)
      opcion = input("\n¿Qué desea hacer? (1:Agregar, 2:Usar, 3:Salir): ")
      if opcion == "1":
        item = input("Nombre del ítem: ")
        cantidad = float(input("Cantidad a agregar: "))
        agregar_stock(inventario, item, cantidad)
      elif opcion == "2":
        item = input("Nombre del ítem: ")
        cantidad = float(input("Cantidad a usar: "))
        usar_stock(inventario, item, cantidad)
      elif opcion == "3":
        break
    
    print("Programa finalizado.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Cómo puedo añadir un nuevo par clave-valor a un diccionario existente en Python?", "En una función, ¿qué significa que un diccionario se pasa 'por referencia'?"
    • Estructura del Código: "Quiero hacer un menú simple en un programa de consola. El usuario debe poder elegir entre 3 opciones. ¿Qué estructura de bucle y condicionales me recomiendas?"

3. Caso de Ingeniería Civil: Calculadora de Peso Estructural (Diccionarios y Funciones)

  • Paso a Paso del Código:

    1. Crear un diccionario que funcione como una base de datos de densidades. La clave será el nombre del material y el valor será su densidad en kg/m³.
    2. Crear una función calcular_peso que reciba el diccionario de densidades, el nombre del material y su volumen.
    3. Dentro de la función, buscar la densidad del material en el diccionario.
    4. Si el material existe, calcular y devolver el peso (densidad * volumen). Si no, devolver un mensaje de error o None.
    5. En el programa principal, pedir al usuario el tipo de material y las dimensiones del elemento para calcular su volumen.
    6. Llamar a la función calcular_peso y mostrar el resultado.
  • Código de Ejemplo en Colab:

    # --- CALCULADORA DE PESO DE ELEMENTOS ESTRUCTURALES ---
    
    # 1. Base de datos de densidades (kg/m³)
    DENSIDADES = {
        "concreto": 2400,
        "acero": 7850,
        "madera": 700,
        "aluminio": 2700
    }
    
    # 2. Función para el cálculo principal
    def calcular_peso(db_densidades, material, volumen):
      """Busca la densidad de un material y calcula su peso dado un volumen."""
      material = material.lower() # Convertir a minúsculas para evitar errores
      if material in db_densidades:
        densidad = db_densidades[material]
        peso = densidad * volumen
        return peso
      else:
        return None # Indica que el material no fue encontrado
    
    # 5. Programa principal
    print("⚖️ Bienvenido a la Calculadora de Peso Estructural")
    
    material_usuario = input(f"Ingrese el material ({', '.join(DENSIDADES.keys())}): ")
    volumen_usuario = float(input("Ingrese el volumen del elemento (en m³): "))
    
    # 6. Llamar a la función y mostrar resultado
    peso_calculado = calcular_peso(DENSIDADES, material_usuario, volumen_usuario)
    
    print("\n--- RESULTADO ---")
    if peso_calculado is not None:
      print(f"Un elemento de {material_usuario} con un volumen de {volumen_usuario} m³ pesa aproximadamente {peso_calculado:.2f} kg.")
    else:
      print(f"Error: El material '{material_usuario}' no se encuentra en la base de datos.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Cómo puedo acceder al valor de un diccionario si tengo su clave en Python?", "¿Qué pasa si intento acceder a una clave que no existe en un diccionario? ¿Cómo puedo evitar que mi programa falle por eso?"
    • Estructura del Código: "Escribe una función que reciba un diccionario y una clave como parámetros. La función debe devolver el valor asociado a esa clave. Si la clave no existe, debe devolver el mensaje 'No encontrado'."

Continuamos con el plan de estudio detallado para las Semanas 6 y 7, un bloque fundamental para que los estudiantes aprendan a crear programas robustos y a gestionar su trabajo como profesionales.

Semanas 6 y 7: Haciendo el Código “a Prueba de Balas” y Guardando el Progreso (8 - 19 de septiembre)

En estas semanas, nos enfocaremos en dos aspectos cruciales de la programación profesional. Primero, aprenderemos a anticipar y gestionar errores con try...except, para que nuestros programas no “crasheen” o se detengan inesperadamente ante una entrada inválida del usuario. Segundo, introduciremos conceptualmente el porqué de Git y GitHub, el sistema estándar en la industria para guardar “fotografías” de nuestro progreso y colaborar en equipo.

Situaciones de Interés para Iniciar

  1. Situación de Interés en Ingeniería Agrícola sprayer️: Un operador de campo necesita una herramienta en su tablet para calcular la tasa de aplicación de un agroquímico. El programa debe pedirle el área a tratar y el volumen total de mezcla. El problema: ¿Qué pasa si el operador, por error, escribe “doscientos” en lugar de “200” o ingresa un área de 0? El programa debe ser lo suficientemente robusto para manejar estos errores sin cerrarse. El contexto Git: Una vez que el programa funcione, ¿cómo guardamos esta versión estable antes de añadirle nuevas funciones, como un conversor de unidades?

  2. Situación de Interés en Ingeniería Agroindustrial 🌡️: Se requiere un programa para estimar las necesidades energéticas de un proceso de calentamiento. El programa pide la masa del producto a calentar y el cambio de temperatura deseado. El problema: El usuario podría ingresar valores negativos o texto. El programa debe validar que las entradas sean números positivos y lógicos para el cálculo. El contexto Git: Desarrollas una primera versión. ¿Cómo podrías compartir tu código con un colega de ingeniería mecánica para que él añada los cálculos de eficiencia del intercambiador de calor, trabajando ambos en el mismo proyecto sin pisarse el trabajo?

  3. Situación de Interés en Ingeniería Civil 📉: Un estudiante de geotecnia está creando un script para calcular el factor de seguridad de un talud simple. El programa pide la cohesión del suelo, el ángulo de fricción y el peso del material. El problema: Los cálculos matemáticos (como la tangente de 90 grados) pueden generar errores. Además, el usuario puede ingresar datos no numéricos. El programa debe “atrapar” estos errores y guiar al usuario para que corrija la entrada. El contexto Git: ¿Cómo mantienes un historial de todas las versiones de tu modelo de cálculo, para poder volver a una versión anterior si descubres que un cambio nuevo introdujo un error?

Resolución de Situaciones y Guía de Estudio

A continuación, la solución a cada escenario, centrada en el manejo de errores.

1. Caso de Ingeniería Agrícola: Calculadora de Dosis Robusta (try...except)

  • Paso a Paso del Código:

    1. Iniciar un bucle while para permitir múltiples cálculos.
    2. Dentro del bucle, envolver todo el bloque de petición de datos y cálculo en un try:.
    3. Pedir al usuario el área y el volumen.
    4. Convertir las entradas a float. Si el usuario ingresa texto, esto generará un ValueError.
    5. Verificar si el área es cero para evitar un ZeroDivisionError.
    6. Si todo es correcto, calcular la dosis y mostrar el resultado.
    7. Definir los bloques except:
      • except ValueError: para atrapar errores de conversión de texto a número.
      • except ZeroDivisionError: para atrapar el error de división por cero.
      • except Exception as e: como una red de seguridad para cualquier otro error inesperado.
    8. Preguntar al usuario si desea realizar otro cálculo para controlar el bucle while.
  • Código de Ejemplo en Colab:

    # --- CALCULADORA ROBUSTA DE DOSIS DE AGROQUÍMICOS ---
    
    print(" sprayer️ Bienvenido a la Calculadora de Tasa de Aplicación")
    
    while True:
      try:
        # 3 y 4. Petición y conversión de datos dentro del 'try'
        area_ha = float(input("\nIngrese el área a tratar (en hectáreas): "))
        volumen_l = float(input("Ingrese el volumen total de la mezcla (en litros): "))
    
        # 5. Verificación para evitar división por cero
        if area_ha <= 0:
          print("❌ Error: El área debe ser un número positivo mayor que cero.")
          continue # Vuelve al inicio del bucle
    
        # 6. Cálculo
        tasa_aplicacion = volumen_l / area_ha
    
        # Mostrar resultado
        print("\n--- RESULTADO ---")
        print(f"La tasa de aplicación requerida es de {tasa_aplicacion:.2f} litros por hectárea.")
    
      # 7. Manejo de errores específicos
      except ValueError:
        print("❌ Error: Por favor, ingrese únicamente valores numéricos.")
      except ZeroDivisionError: # Este caso ya lo controlamos con el 'if', pero es buena práctica tenerlo
        print("❌ Error: El área no puede ser cero.")
      except Exception as e:
        print(f"Ocurrió un error inesperado: {e}")
    
      # 8. Control del bucle
      otro_calculo = input("\n¿Desea realizar otro cálculo? (s/n): ")
      if otro_calculo.lower() != 's':
        break # Sale del bucle
    
    print("Programa finalizado.")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "Explícame qué es una 'excepción' en programación. ¿Por qué es mejor 'pedir perdón que pedir permiso' (usar try-except) en Python?"
    • Estructura del Código: "Escribe un esqueleto de código en Python que pida un número al usuario y lo use en un cálculo, pero que no falle si el usuario escribe texto en su lugar."
    • Resolución Guiada: "Mi programa de división a veces se detiene con un errorZeroDivisionError. ¿Cómo usotry-exceptpara atrapar específicamente ese error y mostrar un mensaje personalizado?"

2. Caso de Ingeniería Agroindustrial: Validación de Datos de Proceso

  • Paso a Paso del Código:

    1. Definir constantes físicas (como el calor específico del producto).
    2. Crear una función calcular_energia que contenga la lógica de cálculo y validación.
    3. Dentro de la función, usar try-except para asegurar que las entradas son numéricas.
    4. Dentro del try, usar un if para validar que los números sean lógicos (positivos). Si no lo son, se puede usar raise ValueError("Mensaje de error") para generar un error intencionalmente que será atrapado por el except.
    5. Si los datos son válidos, realizar el cálculo y devolver la energía.
    6. El programa principal llamará a esta función y manejará la impresión de resultados o errores.
  • Código de Ejemplo en Colab:

    # --- CALCULADORA DE NECESIDADES ENERGÉTICAS ---
    
    # 1. Constante (ej: calor específico del agua en J/kg°C)
    CALOR_ESPECIFICO = 4186
    
    def calcular_energia_requerida(masa_kg, temp_inicial, temp_final):
      """Calcula la energía (en Joules) para calentar una masa. Valida las entradas."""
      try:
        # 3. Conversión a float
        masa = float(masa_kg)
        t_ini = float(temp_inicial)
        t_fin = float(temp_final)
    
        # 4. Validación lógica
        if masa <= 0 or (t_fin <= t_ini):
          raise ValueError("La masa debe ser positiva y la temperatura final mayor a la inicial.")
    
        # 5. Cálculo Q = m * c * ΔT
        delta_temp = t_fin - t_ini
        energia_j = masa * CALOR_ESPECIFICO * delta_temp
        return energia_j, None # Devuelve el resultado y ningún error
    
      except ValueError as e:
        return None, str(e) # Devuelve nada en el resultado y el mensaje de error
    
    # Programa Principal
    print("🌡️ Calculadora de Energía para Calentamiento de Productos")
    m_str = input("Ingrese la masa del producto (kg): ")
    ti_str = input("Ingrese la temperatura inicial (°C): ")
    tf_str = input("Ingrese la temperatura final (°C): ")
    
    energia, error = calcular_energia_requerida(m_str, ti_str, tf_str)
    
    if error:
      print(f"\n❌ Error en el cálculo: {error}")
    else:
      print(f"\n⚡ Energía requerida: {energia / 1000:.2f} kJ (kiloJoules)")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Puedo tener múltiples bloques 'except' para un solo 'try'? ¿Cómo funciona?"
    • Resolución Guiada: "Dentro de un bloque 'try', ¿cómo puedo verificar si un número es negativo y, si lo es, detener el cálculo y mostrar un mensaje de error personalizado?", "Explícame qué hace 'raise ValueError' y en qué situación lo usaría."

3. Caso de Ingeniería Civil: Verificador de Taludes Robusto

  • Paso a Paso del Código:

    1. Importar el módulo math para funciones trigonométricas.
    2. Definir la función principal de cálculo.
    3. Envolver las entradas y los cálculos en un bloque try-except muy amplio.
    4. Dentro del try, convertir las entradas a float.
    5. Realizar el cálculo del factor de seguridad. La función math.tan() puede generar un error si el ángulo es de 90 grados, pero el try-except general lo atrapará.
    6. En el bloque except, en lugar de diferenciar errores, se puede mostrar un mensaje genérico indicando que los datos son inválidos, guiando al usuario a revisar los números ingresados.
    7. Esto simplifica el código cuando los posibles errores matemáticos son complejos, asegurando que el programa nunca falle.
  • Código de Ejemplo en Colab:

    # --- VERIFICADOR SIMPLIFICADO DE FACTOR DE SEGURIDAD ---
    import math
    
    def calcular_fs_talud(cohesion, peso, angulo_friccion_grados):
      """Calcula un factor de seguridad simplificado. Atrapa cualquier error de cálculo."""
      try:
        # 4. Conversión a números
        c = float(cohesion)
        w = float(peso)
        phi = float(angulo_friccion_grados)
    
        # Validación lógica básica
        if c < 0 or w <= 0 or not (0 <= phi < 90):
          print("⚠️ Advertencia: Datos fuera de rango físico esperado.")
          return # Sale de la función si los datos son ilógicos
    
        # 5. Cálculo (puede generar errores matemáticos)
        # Convertir ángulo a radianes para la función tan()
        phi_rad = math.radians(phi)
        fuerza_resistente = c + w * math.cos(phi_rad) * math.tan(phi_rad)
        fuerza_actuante = w * math.sin(phi_rad)
    
        fs = fuerza_resistente / fuerza_actuante
        print(f"✅ Factor de Seguridad calculado: {fs:.3f}")
        if fs > 1.5:
          print("Interpretación: El talud se considera estable bajo estas condiciones.")
        else:
          print("Interpretación: Se requiere un análisis más detallado. Factor de seguridad bajo.")
    
      # 6. Atrapa cualquier error (numérico, matemático, etc.)
      except (ValueError, ZeroDivisionError):
        print("❌ Error: Datos inválidos. Por favor, revise los números ingresados.")
      except Exception as e:
        print(f"❌ Ocurrió un error de cálculo inesperado: {e}")
    
    # Programa Principal
    print("📉 Verificador de Estabilidad de Taludes")
    c_str = input("Ingrese la cohesión del suelo (kPa): ")
    w_str = input("Ingrese el peso de la masa de suelo (kN): ")
    phi_str = input("Ingrese el ángulo de fricción interna (°): ")
    
    calcular_fs_talud(c_str, w_str, phi_str)
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es el módulo 'math' en Python y qué tipo de funciones contiene?", "¿Por qué las funciones trigonométricas en Python (sin,cos,tan) esperan los ángulos en radianes y no en grados?"
    • Resolución Guiada: "Escribe el código en Python para convertir un ángulo de grados a radianes.", "Quiero un solo bloque 'except' que atrape tantoValueErrorcomoZeroDivisionError. ¿Cómo lo escribo?"

El siguiente es el detalle para la Semana 8, un momento clave donde los estudiantes consolidan todo lo aprendido en el primer bloque del curso.

Semana 8: HITO 1 - Integrando Todo: Tu Primer Proyecto de Programación (22 - 26 de septiembre)

Esta semana es diferente. No introduciremos conceptos nuevos. En su lugar, nos dedicaremos por completo a nuestro primer gran hito: construir un programa completo, funcional y robusto desde cero. Es el momento de conectar todas las piezas que hemos aprendido (variables, condicionales, bucles, funciones, diccionarios y manejo de errores) para crear una herramienta de ingeniería útil. El trabajo de esta semana culminará con la entrega de la Tarea 1.

A continuación se presentan las alternativas de proyecto para el Hito 1 (Tarea 1), diseñadas específicamente para los perfiles de Ingeniería Civil, Agrícola y Agroindustrial.

Nota Importante: La estructura de la entrega y los recursos de apoyo son los mismos para las tres Ingenierías. La “Checklist de Entrega”, los “Consejos para el Éxito” y los “Prompts Sugeridos para IA”, que se muestran sólo para Ingeniería Civil. El objetivo es el mismo: integrar todos los conceptos del Bloque 1 en una herramienta funcional.

Opción para Ingeniería Civil: Calculadora de Costos de Materiales para Cimientos

El objetivo es desarrollar una calculadora en Python que estime la cantidad y el costo de los materiales necesarios para construir un cimiento de concreto simple (zapata aislada). El programa debe ser interactivo y fácil de usar para un ingeniero o maestro de obra.

Requisitos Funcionales:

  1. Interfaz de Usuario en Consola: El programa debe presentar un menú claro y ejecutarse en un bucle, permitiendo al usuario realizar múltiples cálculos hasta que decida salir.
  2. Entrada de Datos: Debe solicitar al usuario las dimensiones del cimiento:
    • Largo (metros)
    • Ancho (metros)
    • Altura o peralte (metros)
  3. Base de Datos de Costos: El programa debe usar un diccionario para almacenar los costos unitarios de los materiales. Por ejemplo:
    • Cemento (USD por saco de 42.5 kg)
    • Arena (USD por m³)
    • Grava (USD por m³)
    • Agua (USD por m³)
  4. Cálculos Modulares: La lógica de cálculo debe estar separada en funciones:
    • Una función para calcular el volumen del cimiento.
    • Una función que, a partir del volumen, calcule la cantidad de cada material (usando una dosificación estándar, ej. para 1 m³ de concreto se necesitan 7 sacos de cemento, 0.6 m³ de arena, 0.8 m³ de grava y 0.2 m³ de agua).
    • Una función que, a partir de las cantidades y los costos unitarios, calcule el costo total del proyecto.
  5. Robustez: El programa debe utilizar manejo de errores (try-except) para validar todas las entradas del usuario, evitando que el programa se detenga por ingresos inválidos (texto en lugar de números, valores negativos, etc.).
  6. Salida de Resultados: Debe presentar un resumen claro y bien formateado que incluya el volumen total, la cantidad de cada material requerido y el costo total estimado.

Recursos y Ayudas para el Hito 1

Esta semana, el rol del docente es ser un guía y un consultor. El código no se entrega “hecho”, sino que se ayuda a los estudiantes a construirlo.

  • Checklist de Entrega:
    • Código Fuente: Un único archivo .py (o un enlace a un Google Colab Notebook) con el código completo.
    • Comentarios: El código debe estar comentado, explicando las partes más importantes, especialmente la lógica de las funciones.
    • Video Demostración (Opcional, pero recomendado): Un video corto (1-2 minutos) donde el estudiante muestra el programa en ejecución, incluyendo cómo maneja una entrada correcta y una incorrecta.
  • Consejos para el Éxito:
    1. Planifica Primero, Programa Después: Antes de escribir una sola línea de código, dibuja en un papel el flujo del programa. ¿Qué pregunta harás primero? ¿Qué función llamará a cuál?
    2. Construye en Pequeños Pasos: No intentes hacerlo todo de una vez. Primero, haz que el cálculo del volumen funcione. Luego, añade el cálculo de materiales. Después, el de costos. Y al final, el bucle principal y el manejo de errores.
    3. Prueba Constantemente: Después de cada pequeño paso, prueba tu código para asegurarte de que funciona como esperas.
    4. Nombra Bien tus Variables y Funciones: calcular_costo_total() es mucho más claro que calc(). Un buen nombramiento hace tu código más fácil de leer y depurar.
  • 💡 Prompts Sugeridos para IA:
    • Planificación: "Estoy empezando un proyecto para una calculadora de costos en Python. ¿Cómo puedo descomponer este gran problema en funciones más pequeñas y manejables? Dame una estructura de funciones sugerida."
    • Depuración: "Mi programa me da un error que no entiendo: [pegar el error]. Este es el bloque de código que lo causa: [pegar el código]. ¿Puedes explicarme qué significa este error y dónde podría estar el problema?"
    • Lógica de Código: "Tengo un diccionario con precios, comoprecios = {‘cemento’: 8, ‘arena’: 20}. También tengo otro diccionario con las cantidades necesarias, comocantidades = {‘cemento’: 14, ‘arena’: 1.2}. ¿Cómo puedo escribir un bucle en Python para calcular el costo total multiplicando las cantidades por sus precios correspondientes?"
    • Refactorización: "Este es el código de mi función [pegar función]. Funciona, pero se ve muy largo y repetitivo. ¿Puedes darme sugerencias para hacerlo más corto y limpio?"

Opción para Ingeniería Agrícola: Calculadora de Plan de Fertilización

Consigna del Proyecto

El objetivo es desarrollar una calculadora que ayude a un agricultor a determinar las necesidades de fertilizantes y su costo estimado para un cultivo específico en una superficie determinada.

Requisitos Funcionales:

  1. Interfaz de Usuario en Consola: El programa debe presentar un menú que permita al usuario seleccionar un cultivo, ingresar el área y ver los resultados. Debe ejecutarse en un bucle while para realizar múltiples consultas.
  2. Entrada de Datos:
    • El usuario debe poder elegir un cultivo de una lista predefinida (ej. Maíz, Tomate, Papa).
    • Debe solicitar el área a sembrar (en hectáreas).
  3. Base de Datos (Diccionarios):
    • Un diccionario principal almacenará los requerimientos nutricionales (en kg/ha) para cada cultivo. Ejemplo: python REQUERIMIENTOS = { "maiz": {"N": 120, "P": 60, "K": 60}, "tomate": {"N": 150, "P": 80, "K": 200} }
    • Otro diccionario almacenará el costo de los fertilizantes simples. Ejemplo: python COSTOS_FERTILIZANTE = { "urea_usd_saco_50kg": 25.00, # Aporta Nitrógeno (N) "fosfato_usd_saco_50kg": 30.00 # Aporta Fósforo (P) }
  4. Cálculos Modulares (Funciones):
    • Una función que, a partir del cultivo y el área, calcule los kilogramos totales necesarios de cada nutriente (N, P, K).
    • Una función que calcule cuántos sacos de un fertilizante simple se necesitan (ej. la urea tiene aprox. 46% de N, por lo que 1 saco de 50kg aporta ~23kg de N).
    • Una función que calcule el costo total de los fertilizantes.
  5. Robustez (try-except): El programa debe validar que el área ingresada sea un número positivo y manejar cualquier otro error de entrada sin detenerse.
  6. Salida de Resultados: Presentar un resumen claro que indique: los kg totales de N, P, K necesarios, el número de sacos de cada fertilizante a comprar y el costo total estimado.

Opción para Ingeniería Agroindustrial: Calculadora de Costos para Lote de Producción

Consigna del Proyecto

El objetivo es desarrollar una herramienta que calcule los costos de materia prima para producir un lote de un producto procesado, como mermelada o néctar.

Requisitos Funcionales:

  1. Interfaz de Usuario en Consola: Deberá tener un menú principal que se ejecute en un bucle while, permitiendo al usuario cotizar diferentes producciones hasta que decida salir.
  2. Entrada de Datos:
    • El usuario debe poder seleccionar el producto a fabricar (ej. Mermelada de Fresa, Néctar de Mango).
    • Debe solicitar la cantidad de producto final deseada (en kilogramos).
  3. Base de Datos (Diccionarios):
    • Un diccionario principal almacenará las “recetas” o formulaciones. Indicará cuánta materia prima se necesita por cada kg de producto final. Ejemplo: python RECETAS = { "mermelada_fresa": {"fruta_kg": 1.1, "azucar_kg": 0.6, "pectina_g": 5}, "nectar_mango": {"pulpa_fruta_kg": 0.5, "agua_L": 0.6, "azucar_kg": 0.1} }
    • Otro diccionario almacenará el costo unitario de cada materia prima. Ejemplo: python COSTOS_INGREDIENTES = { "fruta_kg": 1.50, "azucar_kg": 0.90, "pectina_g": 0.05, "pulpa_fruta_kg": 1.20, "agua_L": 0.01 }
  4. Cálculos Modulares (Funciones):
    • Una función que, a partir del producto y la cantidad deseada, calcule la cantidad necesaria de cada ingrediente.
    • Una función que calcule el costo total de la materia prima para el lote.
  5. Robustez (try-except): Validar que la cantidad de producción ingresada sea un número positivo y manejar otros errores de entrada.
  6. Salida de Resultados: Mostrar un “desglose de producción” claro que liste la cantidad de cada ingrediente requerido y el costo total estimado para producir el lote.

Continuemos con el Bloque 2, una fase emocionante donde los estudiantes transformarán sus conocimientos en aplicaciones más robustas y profesionales.

Semana 9: ¡Salimos de Colab! El Entorno Profesional (29 de septiembre - 3 de octubre)

Esta semana marca un punto de inflexión en el curso. Daremos nuestro primer paso fuera del entorno de aprendizaje de Google Colab para entrar al mundo del desarrollo de software profesional. Aprenderemos a estructurar nuestros proyectos en archivos .py, a gestionar dependencias con entornos virtuales y a ejecutar nuestros programas desde la terminal, usando una herramienta estándar en la industria como Visual Studio Code (VSCode).

Situación de Interés General: La Profesionalización de tu Herramienta

Imagina el siguiente escenario, aplicable a cualquiera de los proyectos del Hito 1:

Tu calculadora de costos (de cimientos, de fertilizantes o de producción) ha sido un éxito. Es tan útil que tu supervisor o un colega quiere empezar a usarla regularmente. Sin embargo, pedirle que abra un Google Colab Notebook cada vez que necesita un cálculo no es práctico ni profesional. Además, quieren integrar tu herramienta con otros sistemas en el futuro.

El reto: Se te ha encargado la tarea de convertir tu “cuaderno de prototipos” en un “programa” formal. Debe ser un script de Python (.py) independiente, limpio y ejecutable desde cualquier computador que tenga Python instalado, sin necesidad de un navegador web. ¿Cómo realizamos esta transición?

Resolución y Guía de Estudio: Migrando tu Proyecto a VSCode

El objetivo de esta semana es que cada estudiante tome el código de su Tarea 1 y lo refactorice en un proyecto local estructurado.

  • Paso a Paso de la Migración:

    1. Instalación: Asegurarse de que todos tengan Python y VSCode instalados en sus computadores.
    2. Preparar el Terreno: Crear una nueva carpeta en el computador para el proyecto (ej. MiCalculadoraProfesional). Abrir esta carpeta con VSCode (Archivo > Abrir Carpeta...).
    3. Configurar el Entorno Virtual (venv): Abrir una nueva terminal dentro de VSCode (Terminal > Nuevo terminal). Ejecutar los comandos para crear y activar un entorno virtual. Esto aísla las dependencias del proyecto. bash # Crear el entorno python -m venv venv # Activar el entorno (en Windows) .\venv\Scripts\activate # Activar el entorno (en macOS/Linux) source venv/bin/activate
    4. Crear el Script Principal: Crear un nuevo archivo dentro de VSCode llamado, por ejemplo, main.py.
    5. Trasladar y Refactorizar el Código: Copiar el código de las celdas de Colab al archivo main.py. La clave aquí es organizarlo de manera estructurada (ver el código de ejemplo más abajo). Las definiciones de funciones van primero, y el código que “ejecuta” el programa va dentro de una función main().
    6. Ejecutar desde la Terminal: En la terminal de VSCode (con el entorno activado), ejecutar el script para probar que funciona exactamente igual que en Colab. bash python main.py
  • Código de Ejemplo: Estructura de un Script Profesional (main.py)

    # 1. IMPORTS: Todas las librerías que se usarán van al inicio.
    # (Para este proyecto, puede que no necesitemos ninguna por ahora)
    import os # Ejemplo de import
    
    # 2. CONSTANTES Y "BASES DE DATOS":
    # Las variables que no cambian (constantes) y los diccionarios de datos
    # se definen aquí, en mayúsculas por convención.
    COSTOS_INGREDIENTES = {
        "fruta_kg": 1.50,
        "azucar_kg": 0.90,
    }
    RECETAS = {
        "mermelada_fresa": {"fruta_kg": 1.1, "azucar_kg": 0.6},
    }
    
    # 3. DEFINICIÓN DE FUNCIONES:
    # Cada función debe hacer una sola cosa bien.
    def calcular_costo_lote(producto, cantidad):
      """Calcula el costo total de materia prima para un lote de producción."""
      # ... (Lógica de la función aquí) ...
      # Se asume que esta función usa los diccionarios de arriba
      costo_total = 100 # Valor de ejemplo
      return costo_total
    
    def mostrar_menu():
      """Imprime las opciones disponibles para el usuario."""
      print("\n--- Menú Principal ---")
      print("1. Calcular costo de lote")
      print("2. Salir")
      return input("Seleccione una opción: ")
    
    # 4. FUNCIÓN PRINCIPAL (main):
    # Esta función controla el flujo principal de la aplicación.
    def main():
      """Punto de entrada y bucle principal del programa."""
      print("🚀 Bienvenido al Sistema de Costeo Agroindustrial")
      while True:
        opcion = mostrar_menu()
        if opcion == '1':
          # Aquí iría el código para pedir los datos y llamar a la función de cálculo
          costo = calcular_costo_lote("mermelada_fresa", 50)
          print(f"El costo estimado es: ${costo:.2f}")
        elif opcion == '2':
          print("Saliendo del programa. ¡Hasta luego!")
          break
        else:
          print("❌ Opción no válida. Intente de nuevo.")
    
    # 5. PUNTO DE ENTRADA:
    # Esta construcción asegura que la función main() solo se ejecute
    # cuando el archivo es corrido directamente. Es una convención estándar.
    if __name__ == "__main__":
      main()
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "Estoy acostumbrado a Google Colab. ¿Cuáles son las ventajas de usar un entorno de desarrollo local como VSCode para proyectos más serios?", "¿Qué es la 'terminal' o 'línea de comandos' y por qué un programador profesional la utiliza tanto?"
    • Estructura del Código: "En un script de Python, ¿cuál es el propósito de la construcciónif name == “main”:? ¿Por qué no simplemente llamo a mi funciónmain()al final del archivo?"
    • Resolución de Problemas: "He copiado mi código de Colab a un archivo .py en VSCode, pero cuando lo ejecuto en la terminal no pasa nada, no me pide ningún dato. ¿Qué podría estar faltando en mi script?" (Respuesta probable: olvidaron llamar a la función principal dentro del bloque if __name__ == "__main__":).
    • VSCode: "¿Qué es una 'extensión' en VSCode? ¿Puedes recomendarme 3 extensiones esenciales para programar en Python?" (Respuesta sugerida: Python de Microsoft, Pylance, Black Formatter).

Continuamos con el plan de estudio para las Semanas 10 y 11, donde introducimos un paradigma que cambiará la forma en que los estudiantes estructuran su código: la Programación Orientada a Objetos (POO).

Semanas 10 y 11: Construyendo con Bloques: La Programación Orientada a Objetos (POO) (6 - 17 de octubre)

Durante estas dos semanas, daremos un paso fundamental para escribir código más organizado, reutilizable y fácil de entender. Aprenderemos a modelar el mundo real dentro de nuestros programas. En lugar de tener datos por un lado y funciones por otro, la POO nos permite crear “bloques de construcción” llamados Objetos. Cada objeto tiene sus propias características (atributos) y sus propios comportamientos (métodos).

La analogía es simple: una class es como el plano de un coche, define todas sus partes y lo que puede hacer. Un object es el coche real que construimos a partir de ese plano; podemos construir muchos coches, y cada uno tendrá su propio color, kilometraje, etc., pero todos compartirán la misma estructura del plano.

Situaciones de Interés para Iniciar

  1. Situación de Interés en Ingeniería Agrícola 🌾: Necesitamos gestionar múltiples parcelas en una finca. Cada parcela tiene su propia área, su propio cultivo y su propio nivel de humedad. Queremos un sistema que nos permita tratar a cada Parcela como una unidad individual, a la que podamos dar órdenes como “regar” o “mostrar estado”.

  2. Situación de Interés en Ingeniería Agroindustrial 🥫: En una planta, cada lote de producción es único: tiene un código, una fecha de elaboración y una cantidad. Se necesita una forma de representar cada LoteDeProduccion como una entidad digital. Esta entidad debe ser capaz de, por sí misma, calcular su propia fecha de vencimiento o generar la información para su etiqueta.

  3. Situación de Interés en Ingeniería Civil 🌉: Un ingeniero está diseñando varios elementos estructurales. En lugar de calcular el volumen y el peso de cada viga rectangular con funciones sueltas, quiere crear un “molde” o plantilla para cualquier VigaRectangular. A partir de esta plantilla, podrá crear vigas virtuales, cada una con sus propias dimensiones, y pedirle a cada una que calcule su propio volumen y peso.

Resolución de Situaciones y Guía de Estudio

A continuación, modelamos cada escenario utilizando clases y objetos en Python.

1. Caso de Ingeniería Agrícola: Modelando una Parcela de Cultivo (class Parcela)

  • Paso a Paso del Código:

    1. Crear un nuevo archivo llamado modelos_agricolas.py.
    2. Dentro, definir la class Parcela:.
    3. Crear el constructor __init__: este método recibirá los atributos iniciales de cada parcela (nombre, área, cultivo, humedad) y los guardará usando self.
    4. Definir un método regar(self, litros_m2): este método modificará el atributo self.humedad.
    5. Definir un método mostrar_estado(self): este método imprimirá un resumen bien formateado de todos los atributos de la parcela.
    6. En el archivo main.py, importar la clase (from modelos_agricolas import Parcela).
    7. Crear dos o más objetos (instancias) de la clase Parcela, cada uno con datos diferentes.
    8. Usar los métodos de cada objeto para interactuar con ellos (ej. regar una parcela y luego mostrar el estado de ambas).
  • Código de Ejemplo:

    Archivo: modelos_agricolas.py

    class Parcela:
      """Representa una parcela de cultivo con sus atributos y acciones."""
      def __init__(self, nombre, area_ha, cultivo_actual, humedad_inicial):
        self.nombre = nombre
        self.area_ha = area_ha
        self.cultivo_actual = cultivo_actual
        self.humedad_porcentaje = humedad_inicial
        print(f"✅ Parcela '{self.nombre}' creada.")
    
      def regar(self, cantidad_litros_por_m2):
        """Simula el riego, aumentando el nivel de humedad."""
        print(f"💧 Regando la parcela '{self.nombre}'...")
        self.humedad_porcentaje += cantidad_litros_por_m2 * 0.1 # Simulación simple
        if self.humedad_porcentaje > 100:
          self.humedad_porcentaje = 100
    
      def mostrar_estado(self):
        """Muestra un resumen de la parcela."""
        print(f"\n--- Estado de la Parcela: {self.nombre} ---")
        print(f"  Área: {self.area_ha} ha")
        print(f"  Cultivo: {self.cultivo_actual}")
        print(f"  Humedad Actual: {self.humedad_porcentaje:.1f}%")
        print("--------------------------------------")

    Archivo: main.py

    from modelos_agricolas import Parcela
    
    # Creamos los objetos
    parcela_norte = Parcela(nombre="Lote Norte", area_ha=5, cultivo_actual="Maíz", humedad_inicial=45.0)
    parcela_sur = Parcela(nombre="Lote Sur", area_ha=10, cultivo_actual="Sorgo", humedad_inicial=35.0)
    
    # Mostramos su estado inicial
    parcela_norte.mostrar_estado()
    parcela_sur.mostrar_estado()
    
    # Interactuamos con un objeto específico
    parcela_sur.regar(cantidad_litros_por_m2=200)
    
    # Mostramos el estado final
    print("\n*** DESPUÉS DEL RIEGO ***")
    parcela_norte.mostrar_estado()
    parcela_sur.mostrar_estado()
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "Explícame el concepto de 'clase' y 'objeto' en POO con una analogía del mundo real, como un molde para galletas y las galletas que horneas.", "En una clase de Python, ¿qué es 'self' y por qué se usa en los métodos y en el constructorinit?"
    • Estructura del Código: "Escribe una clase simple en Python para representar un 'Tractor'. Debe tener atributos como 'modelo' y 'horas_de_uso', y un método llamado 'registrar_trabajo(horas)' que incremente las horas de uso."

2. Caso de Ingeniería Agroindustrial: Modelando un Lote de Producción (class LoteDeProduccion)

  • Paso a Paso del Código:

    1. Crear un archivo modelos_industriales.py. Importar el módulo datetime y timedelta para manejar fechas.
    2. Definir la class LoteDeProduccion:.
    3. En el __init__, guardar los atributos: id_lote, producto, cantidad, fecha_elaboracion.
    4. Definir un método calcular_vencimiento(self, dias_vida_util) que tome la fecha_elaboracion, le sume los días de vida útil y devuelva la fecha de vencimiento.
    5. Definir un método generar_etiqueta(self) que devuelva un string con toda la información del lote, listo para ser impreso.
    6. En main.py, importar la clase, crear objetos de lotes diferentes y usar sus métodos para obtener las etiquetas y fechas de vencimiento.
  • Código de Ejemplo:

    Archivo: modelos_industriales.py

    from datetime import date, timedelta
    
    class LoteDeProduccion:
      """Modela un lote de producción con su información y métodos asociados."""
      def __init__(self, id_lote, producto, cantidad_kg):
        self.id_lote = id_lote
        self.producto = producto
        self.cantidad_kg = cantidad_kg
        self.fecha_elaboracion = date.today() # Asigna la fecha actual
    
      def calcular_vencimiento(self, dias_vida_util):
        """Calcula la fecha de vencimiento a partir de la elaboración."""
        return self.fecha_elaboracion + timedelta(days=dias_vida_util)
    
      def generar_etiqueta(self):
        """Genera un string formateado para la etiqueta del lote."""
        return f"--- ETIQUETA DE LOTE ---\nID: {self.id_lote}\nProducto: {self.producto}\nCantidad: {self.cantidad_kg} kg\nElaborado: {self.fecha_elaboracion.strftime('%Y-%m-%d')}"

    Archivo: main.py

    from modelos_industriales import LoteDeProduccion
    
    # Creamos instancias para diferentes productos
    lote_mermelada = LoteDeProduccion(id_lote="MERM-001", producto="Mermelada de Fresa", cantidad_kg=500)
    lote_nectar = LoteDeProduccion(id_lote="NECT-045", producto="Néctar de Mango", cantidad_kg=1200)
    
    # Usamos los métodos
    vencimiento_mermelada = lote_mermelada.calcular_vencimiento(dias_vida_util=365)
    etiqueta_nectar = lote_nectar.generar_etiqueta()
    
    print(lote_mermelada.generar_etiqueta())
    print(f"Fecha de Vencimiento: {vencimiento_mermelada.strftime('%Y-%m-%d')}\n")
    
    print(etiqueta_nectar)
    vencimiento_nectar = lote_nectar.calcular_vencimiento(dias_vida_util=180)
    print(f"Fecha de Vencimiento: {vencimiento_nectar.strftime('%Y-%m-%d')}")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es un método constructor en POO y cuál es su nombre estándar en Python?", "¿Puedo crear un objeto a partir de una clase sin pasarle todos los parámetros que pide elinit? ¿Qué pasaría?"
    • Resolución Guiada: "Necesito trabajar con fechas en Python. ¿Qué librería debo importar y cómo puedo obtener la fecha de hoy?", "Tengo una fecha, ¿cómo le sumo 30 días para obtener una nueva fecha?"

3. Caso de Ingeniería Civil: Modelando un Elemento Estructural (class VigaRectangular)

  • Paso a Paso del Código:

    1. Crear modelos_civiles.py.
    2. Definir la class VigaRectangular:.
    3. En el __init__, recibir y guardar largo, ancho y alto.
    4. Definir un método calcular_volumen(self) que multiplique las tres dimensiones.
    5. Definir un método calcular_peso(self, densidad_kg_m3) que primero llame a self.calcular_volumen() y luego multiplique el resultado por la densidad recibida. Esto muestra cómo los métodos de un mismo objeto pueden colaborar entre sí.
    6. En main.py, importar la clase. Crear un diccionario de densidades. Crear objetos de vigas y usar sus métodos, pasándoles la densidad correspondiente del diccionario.
  • Código de Ejemplo:

    Archivo: modelos_civiles.py

    class VigaRectangular:
      """Representa una viga rectangular y permite calcular sus propiedades."""
      def __init__(self, id_viga, largo, ancho, alto):
        self.id_viga = id_viga
        self.largo_m = largo
        self.ancho_m = ancho
        self.alto_m = alto
    
      def calcular_volumen(self):
        """Calcula y devuelve el volumen de la viga en metros cúbicos."""
        return self.largo_m * self.ancho_m * self.alto_m
    
      def calcular_peso(self, densidad_kg_m3):
        """Calcula el peso de la viga usando su volumen y una densidad dada."""
        volumen = self.calcular_volumen() # Un método llamando a otro
        peso = volumen * densidad_kg_m3
        return peso

    Archivo: main.py

    from modelos_civiles import VigaRectangular
    
    DENSIDADES = {"concreto": 2400, "acero": 7850}
    
    # Creamos las vigas virtuales
    viga_01 = VigaRectangular(id_viga="V-01", largo=6.0, ancho=0.3, alto=0.5)
    viga_02 = VigaRectangular(id_viga="V-02", largo=8.0, ancho=0.4, alto=0.6)
    
    # Calculamos sus propiedades
    volumen_viga_01 = viga_01.calcular_volumen()
    peso_viga_01 = viga_01.calcular_peso(densidad_kg_m3=DENSIDADES["concreto"])
    
    print(f"--- Viga {viga_01.id_viga} ---")
    print(f"  Volumen: {volumen_viga_01:.2f} m³")
    print(f"  Peso (Concreto): {peso_viga_01:.2f} kg")
    
    peso_viga_02 = viga_02.calcular_peso(densidad_kg_m3=DENSIDADES["concreto"])
    print(f"\n--- Viga {viga_02.id_viga} ---")
    print(f"  Peso (Concreto): {peso_viga_02:.2f} kg")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "En POO, ¿cuál es la diferencia entre un atributo de clase y un atributo de instancia? Dame un ejemplo."
    • Resolución Guiada: "Dentro de un método de una clase, ¿cómo puedo llamar a otro método de la misma clase?", "Quiero que un método de mi clase devuelva dos valores a la vez, por ejemplo, el área y el perímetro. ¿Cómo lo hago?"

Avancemos hacia una de las partes más gratificantes del curso, donde se verá cómo los programas lógicos se transforman en aplicaciones visuales e interactivas.

Semanas 12 y 13: Dando Vida a Nuestros Objetos: Interfaces Gráficas con Streamlit (20 - 31 de octubre)

Durante estas dos semanas, conectaremos todo lo que hemos hecho. Aprenderemos a usar Módulos y Paquetes (como streamlit y nuestras propias clases guardadas en otros archivos) para construir aplicaciones completas. El objetivo principal es tomar las clases que diseñamos en las semanas de POO y crear una interfaz gráfica de usuario (GUI) en formato de página web. Esto permitirá que cualquier persona, sin necesidad de ver o entender el código, pueda utilizar las herramientas que hemos creado.

Situación de Interés General: De la Consola a la Aplicación Web

Tus clases Parcela, LoteDeProduccion o VigaRectangular son potentes y funcionan a la perfección. Sin embargo, para usarlas, un colega tendría que abrir el código, crear los objetos manualmente y llamar a los métodos. Esto es ineficiente y propenso a errores.

El reto: Se te ha asignado la tarea de construir una “fachada” o “panel de control” amigable para tus clases. Debes crear una aplicación web simple donde un usuario pueda ingresar los datos en casillas y botones, y ver los resultados de forma clara y visual, sin tocar una sola línea de código. ¿Cómo usamos Streamlit para “envolver” nuestros objetos en una interfaz gráfica?

Resolución de Situaciones y Guía de Estudio

El objetivo es crear un nuevo script app.py que importe las clases previamente definidas y las utilice como el “motor” de la aplicación Streamlit.

1. Caso de Ingeniería Agrícola: Panel de Control de Parcelas

  • Paso a Paso del Código:

    1. Crear un nuevo archivo, app.py, en la misma carpeta donde tienes modelos_agricolas.py.
    2. En app.py, importar streamlit y la clase Parcela: from modelos_agricolas import Parcela.
    3. Diseñar la interfaz con un título (st.title) y una descripción.
    4. Usar widgets de Streamlit para capturar los datos necesarios para crear una Parcela: st.text_input para el nombre, st.number_input para el área y la humedad, y st.selectbox para el tipo de cultivo.
    5. Añadir un botón st.button("Crear y Analizar Parcela").
    6. Dentro de un if que se activa con el botón, tomar los valores de los widgets, crear una instancia de la clase Parcela.
    7. Llamar al método .mostrar_estado() del objeto creado y mostrar la información en la página.
  • Código de Ejemplo (app.py):

    import streamlit as st
    from modelos_agricolas import Parcela # Importamos nuestra clase
    
    # --- Configuración de la Interfaz ---
    st.set_page_config(page_title="Gestor de Parcelas", page_icon="🌾")
    st.title("🌾 Panel de Control de Parcelas Agrícolas")
    st.write("Crea y gestiona las parcelas de tu finca de forma virtual.")
    
    # --- Formulario de Entrada de Datos ---
    st.header("Registrar Nueva Parcela")
    with st.form("nueva_parcela_form"):
        nombre_parcela = st.text_input("Nombre o ID de la Parcela (ej. Lote-01):")
        area_parcela = st.number_input("Área (en hectáreas):", min_value=0.1, step=0.1)
        cultivo = st.selectbox("Cultivo Actual:", ["Maíz", "Sorgo", "Tomate", "Ninguno"])
        humedad = st.slider("Humedad Inicial (%):", 0, 100, 50)
    
        # Botón de envío del formulario
        submitted = st.form_submit_button("Crear Parcela")
    
    # --- Lógica de la Aplicación ---
    if submitted:
        if not nombre_parcela:
            st.warning("Por favor, ingresa un nombre para la parcela.")
        else:
            # 6. Creamos el objeto con los datos del formulario
            parcela_obj = Parcela(
                nombre=nombre_parcela,
                area_ha=area_parcela,
                cultivo_actual=cultivo,
                humedad_inicial=float(humedad)
            )
            st.success(f"¡Parcela '{parcela_obj.nombre}' creada con éxito!")
    
            # 7. Usamos el método del objeto para mostrar su estado
            # Para mostrarlo en Streamlit, modificamos el método para que devuelva un string
            # O creamos una función que lo formatee aquí.
            st.subheader("Estado Actual de la Parcela")
    
            # Usando st.metric para una visualización más atractiva
            col1, col2, col3 = st.columns(3)
            col1.metric("Área", f"{parcela_obj.area_ha} ha")
            col2.metric("Cultivo", parcela_obj.cultivo_actual)
            col3.metric("Humedad", f"{parcela_obj.humedad_porcentaje:.1f}%")
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Cuál es la diferencia entre un módulo y un paquete en Python?", "Tengo dos archivos .py en la misma carpeta. ¿Cómo importo una clase de un archivo para usarla en el otro?"
    • Streamlit: "¿Qué esst.formen Streamlit y cuándo debería usarlo en lugar de poner los widgets directamente en la página?", "¿Cómo puedo mostrar datos en columnas una al lado de la otra en Streamlit?"

2. Caso de Ingeniería Agroindustrial: Interfaz de Gestión de Lotes

  • Paso a Paso del Código:

    1. Crear app.py. Importar streamlit y la clase LoteDeProduccion.
    2. Diseñar la interfaz con st.title, etc.
    3. Usar widgets para capturar los datos del lote: st.text_input para el ID, st.selectbox para el nombre del producto, st.number_input para la cantidad.
    4. Añadir un slider st.slider para que el usuario defina los “días de vida útil” del producto.
    5. Al presionar un botón, crear una instancia de LoteDeProduccion.
    6. Llamar a los métodos .generar_etiqueta() y .calcular_vencimiento().
    7. Mostrar la etiqueta generada en un st.text_area y la fecha de vencimiento con st.success.
  • Código de Ejemplo (app.py):

    import streamlit as st
    from modelos_industriales import LoteDeProduccion # Importamos la clase
    
    st.title("🥫 Gestor de Lotes de Producción")
    
    with st.expander("➕ Registrar Nuevo Lote de Producción", expanded=True):
        id_lote = st.text_input("ID del Lote (ej. MERM-002):")
        producto = st.selectbox("Producto:", ["Mermelada de Fresa", "Néctar de Mango", "Salsa de Tomate"])
        cantidad = st.number_input("Cantidad Producida (kg):", min_value=1.0)
        vida_util = st.slider("Días de Vida Útil del Producto:", 30, 730, 365)
    
        if st.button("Registrar y Generar Etiqueta"):
            if not id_lote or not producto:
                st.error("El ID del lote y el producto son obligatorios.")
            else:
                # 5. Creamos el objeto
                lote_obj = LoteDeProduccion(id_lote, producto, cantidad)
    
                st.balloons()
                st.subheader("Etiqueta y Datos del Lote Generados")
    
                # 6. Llamamos a los métodos
                etiqueta = lote_obj.generar_etiqueta()
                fecha_vencimiento = lote_obj.calcular_vencimiento(vida_util)
    
                # 7. Mostramos los resultados
                st.text_area("Etiqueta Generada", value=etiqueta, height=150)
                st.success(f"Fecha de Vencimiento Calculada: {fecha_vencimiento.strftime('%d de %B de %Y')}")
  • 💡 Prompts Sugeridos para IA:

    • Streamlit: "¿Cómo puedo hacer que un formulario o una sección de mi app de Streamlit aparezca colapsada por defecto y se expanda al hacer clic?", "Quiero mostrar una fecha en un formato amigable como '07 de Agosto de 2025'. ¿Cómo formateo un objeto de fecha en Python de esa manera?"
    • Integración: "Tengo una clase en un archivo y la estoy usando en mi app de Streamlit. Si hago un cambio en la clase, ¿tengo que reiniciar mi app de Streamlit para que vea los cambios? ¿Cómo funciona eso?"

3. Caso de Ingeniería Civil: Calculadora Visual de Propiedades de Vigas

  • Paso a Paso del Código:

    1. Crear app.py. Importar streamlit, la clase VigaRectangular y el diccionario DENSIDADES.
    2. Diseñar la interfaz.
    3. Usar st.number_input para las dimensiones (largo, ancho, alto).
    4. Usar st.selectbox para que el usuario elija un material. Las opciones del selectbox deben ser las llaves del diccionario DENSIDADES.
    5. Al presionar un botón, crear un objeto VigaRectangular.
    6. Obtener la densidad seleccionada del diccionario.
    7. Llamar a los métodos .calcular_volumen() y .calcular_peso(), pasándole la densidad.
    8. Mostrar los resultados usando st.metric para una visualización de impacto.
  • Código de Ejemplo (app.py):

    import streamlit as st
    from modelos_civiles import VigaRectangular, DENSIDADES # Importamos clase y diccionario
    
    st.title("🌉 Calculadora de Propiedades de Vigas")
    
    st.sidebar.header("Parámetros de la Viga")
    id_viga = st.sidebar.text_input("ID de la Viga:", "V-101")
    largo = st.sidebar.number_input("Largo (m):", value=6.0)
    ancho = st.sidebar.number_input("Ancho (m):", value=0.3)
    alto = st.sidebar.number_input("Alto (m):", value=0.5)
    material = st.sidebar.selectbox("Material:", options=list(DENSIDADES.keys()))
    
    if st.sidebar.button("Calcular Propiedades"):
        # 5. Creamos la instancia
        viga_obj = VigaRectangular(id_viga, largo, ancho, alto)
    
        # 6. Obtenemos la densidad
        densidad_seleccionada = DENSIDADES[material]
    
        # 7. Llamamos a los métodos
        volumen = viga_obj.calcular_volumen()
        peso = viga_obj.calcular_peso(densidad_seleccionada)
    
        st.header(f"Resultados para la Viga: {viga_obj.id_viga}")
    
        # 8. Mostramos resultados con st.metric
        col1, col2 = st.columns(2)
        col1.metric("Volumen", f"{volumen:.2f} m³")
        col2.metric(f"Peso ({material.capitalize()})", f"{peso:,.0f} kg")
    else:
        st.info("Ingrese los parámetros en la barra lateral y presione 'Calcular'.")
  • 💡 Prompts Sugeridos para IA:

    • Streamlit: "¿Cómo puedo crear una barra lateral en mi aplicación de Streamlit para poner allí todos los controles de entrada?", "Tengo un diccionario en Python. ¿Cómo puedo obtener una lista de todas sus llaves para usarla como opciones en unst.selectbox?"
    • Formato de Salida: "En Python, tengo un número muy grande como 125430.7. ¿Cómo puedo formatearlo para que se muestre con comas como separadores de miles y sin decimales, como '125,431'?"

Avancemos a la Semana 14. Esta es una semana conceptualmente muy importante, ya que aborda un pilar fundamental en el desarrollo de aplicaciones interactivas: el manejo del estado.

Semana 14: Dando Memoria a Nuestras Apps: El Manejo de Estado (3 - 7 de noviembre de 2025)

Hasta ahora, nuestras aplicaciones tienen un pequeño problema: no tienen memoria. Cada vez que interactuamos con un widget (un botón, un slider), Streamlit vuelve a ejecutar nuestro script de Python desde el principio. Esto significa que cualquier variable que hayamos creado se reinicia.

El objetivo de esta semana es aprender a solucionar esto. Introduciremos el Manejo de Estado a través de st.session_state, un objeto especial de Streamlit que funciona como un “diccionario con memoria” y que sobrevive a los reinicios del script. Esto nos permitirá crear aplicaciones mucho más complejas y útiles.

Situación de Interés General: Construyendo una Lista Interactiva

Tu aplicación es genial para analizar un solo objeto a la vez (una parcela, un lote, una viga). Pero en el mundo real, los proyectos son más complejos.

  • Ingeniería Agrícola: Un agrónomo no planifica un solo cultivo, sino una secuencia de rotación para los próximos años en la misma parcela.
  • Ingeniería Agroindustrial: Un jefe de planta no gestiona un solo lote, sino una lista de todos los lotes producidos en un día para su trazabilidad.
  • Ingeniería Civil: Un ingeniero de costos no calcula una sola viga, sino que elabora un listado completo de materiales para toda una estructura.

El reto: ¿Cómo permitimos que el usuario agregue elementos a una lista uno por uno, sin que la lista se borre cada vez que hace clic en el botón “Añadir”? Aquí es donde st.session_state se vuelve indispensable.

Resolución de Situaciones y Guía de Estudio

A continuación, implementamos la solución para cada escenario, demostrando el uso de st.session_state.

1. Caso de Ingeniería Agrícola: Planificador de Rotación de Cultivos

  • Paso a Paso del Código:

    1. Importar streamlit.
    2. Inicializar el estado: Al principio del script, verificar si la lista de rotación ya existe en st.session_state. Si no existe, crearla como una lista vacía. Esto es crucial y se hace solo una vez, la primera vez que se ejecuta la app.
    3. Crear los widgets: un st.selectbox para elegir un cultivo y un st.button para añadirlo.
    4. Si se presiona el botón, usar .append() para añadir el cultivo seleccionado a la lista que está guardada en st.session_state.rotacion.
    5. Mostrar siempre el plan de rotación actual, recorriendo la lista almacenada en st.session_state.rotacion.
    6. Añadir un botón de “Limpiar” que reinicie la lista en el estado de sesión.
  • Código de Ejemplo (app.py):

    import streamlit as st
    
    st.title("🌱 Planificador de Rotación de Cultivos")
    
    # 2. Inicialización del estado de sesión
    if 'plan_rotacion' not in st.session_state:
        st.session_state.plan_rotacion = []
    
    # --- Controles para añadir cultivos ---
    cultivos_disponibles = ["Maíz", "Soja", "Trigo", "Girasol", "Barbecho (Descanso)"]
    cultivo_seleccionado = st.selectbox("Seleccione el cultivo para el siguiente ciclo:", cultivos_disponibles)
    
    if st.button("Añadir al Plan de Rotación"):
        # 4. Modificar el estado
        st.session_state.plan_rotacion.append(cultivo_seleccionado)
        st.success(f"Se añadió '{cultivo_seleccionado}' al plan.")
    
    # --- Mostrar el estado actual ---
    st.header("Plan de Rotación Actual")
    
    if not st.session_state.plan_rotacion:
        st.info("Aún no se han añadido cultivos al plan.")
    else:
        for i, cultivo in enumerate(st.session_state.plan_rotacion):
            st.write(f"**Año {i+1}:** {cultivo}")
    
    # 6. Botón para reiniciar el estado
    if st.button("Limpiar Plan"):
        st.session_state.plan_rotacion = []
        st.experimental_rerun() # Forzar la recarga de la app para ver el cambio
  • 💡 Prompts Sugeridos para IA:

    • Conceptuales: "¿Qué es el 'estado' en una aplicación web? Explícamelo con una analogía de un carrito de compras online.", "¿Por qué mi variable en Streamlit se reinicia cada vez que hago clic en un botón? ¿Cómo funciona el ciclo de ejecución de Streamlit?"
    • session_state: "Muéstrame la forma correcta de inicializar una variable en st.session_state para que solo ocurra una vez.", "¿Cuál es la diferencia entrest.session_state.mi_variable = valoryst.session_state[‘mi_variable’] = valor?"

2. Caso de Ingeniería Agroindustrial: Registro de Trazabilidad de Lotes

  • Paso a Paso del Código:

    1. Inicializar st.session_state.lotes como una lista vacía si no existe.
    2. Usar un st.form para agrupar los campos de entrada: id_lote, producto y fecha_elaboracion.
    3. Cuando el formulario se envía, crear un diccionario con los datos del nuevo lote.
    4. Añadir este diccionario a la lista st.session_state.lotes.
    5. Mostrar la lista completa de lotes registrados usando st.dataframe.
  • Código de Ejemplo (app.py):

    import streamlit as st
    import pandas as pd
    from datetime import date
    
    st.title("📦 Registro de Trazabilidad de Lotes")
    
    # 1. Inicializar estado
    if 'lotes_registrados' not in st.session_state:
        st.session_state.lotes_registrados = []
    
    # 2. Formulario para registrar un nuevo lote
    with st.form("form_lote", clear_on_submit=True):
        st.write("### Registrar Nuevo Lote")
        id_lote = st.text_input("ID del Lote:")
        producto = st.text_input("Nombre del Producto:")
        fecha = st.date_input("Fecha de Elaboración", value=date.today())
    
        submitted = st.form_submit_button("Registrar Lote")
    
        if submitted:
            # 3. Crear el diccionario
            nuevo_lote = {
                "ID Lote": id_lote,
                "Producto": producto,
                "Fecha Elaboración": fecha
            }
            # 4. Añadir al estado
            st.session_state.lotes_registrados.append(nuevo_lote)
            st.success(f"Lote {id_lote} registrado con éxito.")
    
    # 5. Mostrar todos los lotes registrados
    st.header("Historial de Lotes Registrados")
    if st.session_state.lotes_registrados:
        # Convertimos la lista de diccionarios a un DataFrame de Pandas para una mejor visualización
        df_lotes = pd.DataFrame(st.session_state.lotes_registrados)
        st.dataframe(df_lotes)
    else:
        st.info("No hay lotes registrados en esta sesión.")
  • 💡 Prompts Sugeridos para IA:

    • session_state: "¿Cómo puedo guardar una lista de objetos de mi propia clase en st.session_state?"
    • Streamlit: "Quiero que los campos de mi formulario se borren después de que el usuario presione 'Enviar'. ¿Cómo lo hago en Streamlit?"
    • Depuración: "Mi lista en st.session_state parece reiniciarse. ¿Cuál podría ser el error en mi código de inicialización? [pegar código de inicialización]".

3. Caso de Ingeniería Civil: Listado de Cómputos Métricos

  • Paso a Paso del Código:

    1. Inicializar st.session_state.listado_materiales como una lista vacía.
    2. Crear una interfaz con columnas (st.columns) para una mejor organización.
    3. En una columna, poner los controles para añadir un nuevo ítem: descripcion, cantidad y unidad.
    4. Al presionar el botón “Añadir”, añadir un diccionario representando el ítem a la lista en st.session_state.
    5. En otra columna, mostrar el listado actual, iterando sobre st.session_state.listado_materiales.
    6. (Opcional Avanzado) Añadir una función para borrar un ítem específico de la lista.
  • Código de Ejemplo (app.py):

    import streamlit as st
    
    st.title("🏗️ Listado de Materiales para Cómputos Métricos")
    
    # 1. Inicializar estado
    if 'materiales' not in st.session_state:
        st.session_state.materiales = []
    
    # 2. Usar columnas para la interfaz
    col1, col2 = st.columns([1, 2])
    
    with col1:
        st.header("Añadir Ítem")
        # 3. Controles
        descripcion = st.text_input("Descripción del Material:")
        cantidad = st.number_input("Cantidad:", min_value=0.1, step=0.1, format="%.2f")
        unidad = st.selectbox("Unidad:", ["m³", "m²", "kg", "sacos", "unidades"])
    
        if st.button("➕ Añadir al Listado"):
            if descripcion and cantidad:
                # 4. Añadir al estado
                nuevo_item = {
                    "Descripción": descripcion,
                    "Cantidad": cantidad,
                    "Unidad": unidad
                }
                st.session_state.materiales.append(nuevo_item)
            else:
                st.warning("La descripción y la cantidad son necesarias.")
    
    with col2:
        st.header("Listado Actual")
        # 5. Mostrar el estado
        if not st.session_state.materiales:
            st.info("El listado está vacío.")
        else:
            # Creamos una tabla improvisada
            for i, item in enumerate(st.session_state.materiales):
                st.markdown(f"**{i+1}. {item['Descripción']}:** {item['Cantidad']} {item['Unidad']}")
    
    # Botón para limpiar todo el listado
    if st.sidebar.button("🗑️ Limpiar todo el listado"):
        st.session_state.materiales = []
        st.experimental_rerun()
  • 💡 Prompts Sugeridos para IA:

    • session_state: "Quiero añadir un botón para eliminar el último elemento que agregué a mi lista en st.session_state. ¿Cómo sería el código para eso?"
    • Streamlit: "¿Hay alguna forma mejor de mostrar una lista de diccionarios en Streamlit que no sea unst.dataframeo un bucleforconst.write? ¿Qué esst.data_editor?"
    • Estructura de Código: "Mi aplicación de Streamlit está creciendo y el archivo app.py es muy largo. ¿Cómo puedo organizar mi código en múltiples archivos e importarlos correctamente?"

Abordemos la penúltima semana del curso, un momento crucial donde todo el aprendizaje del semestre converge en el proyecto final.

Semana 15: HITO 2 - El Proyecto Final: Demostrando tu Poder como Creador (10 - 14 de noviembre)

Esta es la semana cumbre. Todo lo que hemos aprendido, desde la primera variable hasta el manejo de estado, se une aquí. El objetivo de esta semana es que cada uno de ustedes se dedique por completo a desarrollar la Tarea 2, una aplicación web interactiva y funcional que no solo resuelva un problema de ingeniería, sino que también demuestre su habilidad para estructurar código de manera profesional (usando Clases) y crear una experiencia de usuario dinámica (usando Streamlit y st.session_state).

Consignas del Proyecto (Tarea 2)

A continuación se presentan tres opciones de proyecto, una para cada especialidad. Elige la que más te interese. Todas comparten el mismo nivel de complejidad y deben cumplir con los mismos requisitos técnicos.

Opción para Ingeniería Agrícola: Sistema Interactivo de Gestión de Finca

  • Descripción: Evoluciona tu planificador de rotación a un sistema de gestión más completo. El usuario debe poder añadir y gestionar múltiples Parcelas de cultivo en una finca virtual.
  • Requisitos Funcionales:
    1. Gestión de Múltiples Parcelas: La aplicación debe usar st.session_state para mantener una lista de objetos de tu clase Parcela.
    2. Añadir Parcelas: Un formulario permitirá al usuario crear nuevas instancias de Parcela y añadirlas a la lista en el estado de la sesión.
    3. Dashboard Principal: La pantalla principal mostrará un resumen de todas las parcelas existentes (ej. nombre y cultivo actual).
    4. Interactividad por Objeto: El usuario podrá seleccionar una parcela específica de la lista. Al seleccionarla, podrá interactuar con ella:
      • Ver su estado detallado llamando al método .mostrar_estado().
      • Hacer clic en un botón “Regar esta parcela”, que llamará al método .regar() del objeto específico, actualizando su humedad en el session_state. El cambio debe reflejarse inmediatamente en la interfaz.
    5. Interfaz Clara: Utiliza st.expander o st.container para organizar la información de cada parcela de forma ordenada.

Opción para Ingeniería Agroindustrial: Dashboard de Trazabilidad de Producción

  • Descripción: Amplía tu registro de lotes a un dashboard interactivo que no solo registra, sino que también permite buscar y actualizar el estado de los lotes.
  • Requisitos Funcionales:
    1. Registro Continuo: La app usará st.session_state para gestionar una lista de objetos de tu clase LoteDeProduccion.
    2. Formulario de Registro: Un st.form permitirá registrar nuevos lotes, que se añadirán a la lista en el estado.
    3. Visualización en Tabla: La pantalla principal mostrará todos los lotes registrados en una tabla (st.dataframe).
    4. Búsqueda y Filtro: Añade una barra de búsqueda (st.text_input) donde el usuario pueda escribir un id_lote. La aplicación deberá encontrar el objeto correspondiente en la lista del session_state y mostrar su etiqueta detallada.
    5. Actualización de Estado: Al ver un lote específico, debe haber un botón como “Marcar como Despachado”. Al hacer clic, se debe modificar un atributo del objeto (ej. self.estado = "Despachado") y la tabla principal debe reflejar este cambio.

Opción para Ingeniería Civil: Herramienta de Cómputos Métricos y Presupuesto

  • Descripción: Convierte tu listado de materiales en una herramienta completa que gestiona una lista de diferentes elementos estructurales y calcula los totales consolidados.
  • Requisitos Funcionales:
    1. Listado de Elementos: La app usará st.session_state para mantener una lista de objetos de tu clase VigaRectangular (o una clase ElementoEstructural más genérica).
    2. Añadir Elementos: El usuario podrá añadir múltiples elementos a su proyecto (ej. “Viga Comedor”, “Columna Principal”), cada uno con sus propias dimensiones y material.
    3. Visualización del Proyecto: La interfaz mostrará una lista de todos los elementos añadidos al proyecto.
    4. Cálculos Agregados: La aplicación debe recorrer la lista de objetos en st.session_state para calcular y mostrar los totales consolidados del proyecto:
      • Volumen total de Concreto (m³).
      • Peso total de Acero (kg).
      • Costo total preliminar (si se añaden precios).
    5. Generación de Reporte: Un botón “Generar Resumen de Proyecto” que presente de forma limpia todos los totales calculados.

Recursos y Ayudas para el Hito 2

  • Checklist de Entrega:
    • Enlace al Repositorio de GitHub: Con todo el código (app.py, modelos_*.py, requirements.txt).
    • Enlace a la Aplicación Desplegada: La app debe estar funcional en Streamlit Cloud.
    • Estructura de Código: Se evaluará el uso correcto de Clases y Objetos para modelar el problema.
    • Funcionalidad de la Interfaz: Todos los widgets deben funcionar como se espera.
    • Manejo de Estado: El uso de st.session_state debe ser correcto y permitir la interactividad requerida.
    • Claridad y UX: La aplicación debe ser intuitiva y fácil de usar.
  • Consejos para el Éxito:
    1. Diseña tu Estado Primero: Antes de escribir la UI, piensa: ¿Qué información necesito recordar? ¿Será una lista? ¿Un diccionario? ¿Una lista de objetos? Dibuja la estructura de tu st.session_state.
    2. Depura Visualmente: Si no estás seguro de lo que hay en tu estado, añade temporalmente st.write(st.session_state) en tu app. Esto te mostrará en vivo todo lo que está guardado y te ayudará a encontrar errores.
    3. Usa Funciones para la Lógica: No pongas cálculos complejos dentro de un if st.button(...). Crea una función (ej. agregar_material_al_estado) y llámala desde el bloque del botón. Esto mantiene tu código de la interfaz limpio.
  • 💡 Prompts Sugeridos para IA:
    • Estructura y Estado: "Estoy construyendo una app en Streamlit y necesito gestionar una lista de objetos de mi clase 'Producto'. Muéstrame un ejemplo de código completo que inicialice el estado, tenga un formulario para añadir nuevos productos a la lista y muestre la lista actualizada."
    • Depuración: "En mi app de Streamlit, cuando hago clic en un botón para modificar un ítem en una lista dentro de st.session_state, parece que se modifica el ítem equivocado o nada cambia. ¿Cuáles son los errores comunes al actualizar listas de objetos en el estado de sesión?"
    • Funcionalidad Avanzada: "Quiero añadir un botón 'Eliminar' al lado de cada ítem en mi lista mostrada en Streamlit. ¿Cómo puedo pasar el índice o el ID del ítem a la función de borrado cuando se hace clic en el botón?"
    • Organización: "Mi archivo app.py se está haciendo muy grande. ¿Cuál es una buena manera de estructurar un proyecto de Streamlit más complejo en múltiples archivos .py?"

Llegamos a la última y más importante etapa del curso, la Semana 16. Aquí es donde los estudiantes no solo finalizan su trabajo técnico, sino que también aprenden a comunicar su valor, una habilidad esencial para cualquier ingeniero.

Semana 16: Comunicando tu Solución: Despliegue y Presentación Final (17 - 21 de noviembre de 2025)

¡Felicitaciones por llegar a la semana final! Han recorrido un largo camino desde escribir su primera línea de código hasta construir una aplicación web funcional. Esta semana tiene dos objetivos clave: asegurar que su aplicación esté desplegada y accesible para el mundo, y comunicar eficazmente el problema que resolvieron y la solución que crearon. Recuerden: una herramienta brillante es inútil si nadie entiende para qué sirve o cómo usarla.

Guía para la Etapa Final del Proyecto

1. El Paso Final: Asegurando un Despliegue Exitoso

Antes de la presentación, su aplicación debe estar funcionando en Streamlit Cloud. Este es el último paso técnico.

  • Checklist Final de Despliegue:
    • requirements.txt está completo: Abran su terminal (con el entorno activado) y ejecuten pip freeze > requirements.txt una última vez para asegurarse de que todas las librerías (streamlit, pandas, etc.) están listadas. Este es el error de despliegue más común.
    • El repositorio de GitHub es público: Verifiquen en la configuración de su repositorio que la visibilidad sea “Public”.
    • Las rutas de archivos son relativas: Si cargan algún archivo (como un CSV o una imagen), asegúrense de que la ruta en el código no sea local (ej. C:\...), sino relativa al proyecto.
    • Prueba de fuego: Pídanle a un compañero que intente abrir el enlace de su aplicación desplegada en su propio computador. Si a él le funciona, ¡están listos!

2. Estructura de la Presentación Final (Formato Sugerido: 7 minutos)

Cada estudiante tendrá un tiempo limitado para presentar su proyecto. La clave es ser conciso, claro y centrarse en la demostración.

  • Introducción (1 minuto): El “Porqué”
    • Preséntate.
    • Describe el problema de ingeniería que tu aplicación resuelve. ¿Por qué es un problema relevante para tu disciplina (agrícola, agroindustrial o civil)?
    • Menciona brevemente cuál fue tu solución: “Para resolver esto, construí una aplicación interactiva en Streamlit que…”.
  • DEMOSTRACIÓN EN VIVO (4-5 minutos): El “Cómo” y el “Qué”
    • ¡Esta es la parte más importante! Comparte la pantalla de tu navegador con la aplicación ya cargada.
    • Guía al usuario: Explica la interfaz. “¿Qué ve el usuario al entrar? ¿Dónde están los controles?”.
    • Caso de uso: Realiza un caso de uso práctico. Por ejemplo: “Imaginemos que necesitamos añadir dos vigas y una columna a nuestro proyecto. Primero, ingreso los datos de la viga 1…”.
    • Muestra la magia: Demuestra la funcionalidad clave de tu app. Si es el planificador de rotación, muestra cómo se añade un cultivo a la lista en session_state. Si es la calculadora de costos, muestra cómo se actualizan los totales agregados. Explica los resultados que la aplicación genera.
  • Conclusión y Visión a Futuro (1 minuto): El “Y ahora qué”
    • Resume el principal valor de tu herramienta en una frase.
    • Menciona una posible mejora o una nueva funcionalidad que le añadirías en el futuro. (Ej. “Como siguiente paso, me gustaría que la app enviara un reporte por email.”).
    • Agradece y abre el espacio para preguntas.

3. Claves para una Demostración en Vivo Exitosa

  • Prepárate: Ten la pestaña del navegador con tu app de Streamlit ya cargada y lista antes de empezar a presentar. No la abras en vivo.
  • Habla antes de hacer clic: Explica lo que vas a hacer antes de hacerlo. “Ahora voy a hacer clic en el botón ‘Calcular’ y veremos cómo la aplicación genera el resumen de costos en la parte de abajo”.
  • No leas el código: La audiencia quiere ver la aplicación en acción, no el código fuente. Puedes mencionar la tecnología (“Esto lo logré usando la clase Lote y st.session_state…”), pero no muestres el código a menos que te lo pregunten.
  • Ten un Plan B: Las demos en vivo a veces fallan. Ten capturas de pantalla o un video corto de tu app funcionando como respaldo, por si la conexión a internet falla.

💡 Prompts Sugeridos para IA para Perfeccionar tu Presentación

  • Guion y Narrativa: "Ayúdame a crear un guion de 1 minuto para la introducción de mi proyecto. El proyecto es una 'Herramienta de Cómputos Métricos para Ingeniería Civil'. Quiero que sea impactante y que deje claro el problema que resuelve."
  • Preparación de Preguntas: "¿Cuáles son las 3 preguntas técnicas más probables que me harían sobre mi proyecto de Streamlit que usa POO y manejo de estado? Dame ejemplos de respuestas claras y concisas."
  • Comunicación: "Voy a hacer una demostración en vivo de mi software. Dame 5 consejos sobre cómo hablar y qué hacer para mantener a la audiencia interesada y para que mi explicación sea muy clara."
  • Síntesis: "Este es el resumen de mi proyecto [pegar una descripción de 2-3 párrafos]. Ayúdame a condensarlo en una sola frase poderosa para mi conclusión."