Saltar al contenido
Volver al inicio 100 Días de Código en Python — Día 10: Funciones con Salida (return) y la Calculadora

100 Días de Código en Python — Día 10: Funciones con Salida (return) y la Calculadora

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 10.

Este tutorial adapta pedagógicamente el Día 10. Las secciones 📝 Ejercicio original del curso provienen de los archivos del curso. Los retos 🟢🟡🟠🔴, el proyecto extra y el proyecto integrador son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.


Tabla de contenidos

  1. Antes de empezar: el tercer "sabor" de las funciones
  2. Funciones con salida: return
  3. Varios return y retorno anticipado
  4. Docstrings: documentar tus funciones
  5. Funciones como valores: guardarlas en variables y diccionarios
  6. 🚀 Proyecto del día: la Calculadora
  7. 🌟 Proyecto extra: Conversor de Unidades
  8. 🏆 Proyecto integrador del Día 10: Informe Académico 3.0
  9. 🤖 Programar con apoyo de IA
  10. 🛠️ Correcciones técnicas al material original
  11. 📋 Matriz de trazabilidad
  12. 📦 Evidencias de aprendizaje del Día 10

0. Antes de empezar

(Fuentes: 072 - Day 10 Goals- what we will make by the end of the day.md, 077 - How to Get a Good Night's Sleep.md)

Ya conocemos dos "sabores" de funciones:

Sabor Ejemplo Día
Simple def saludar(): 6
Con entradas def saludar(nombre): 8
Con salida def sumar(a, b): return a + b 10 (hoy)

Con el tercer sabor construiremos una calculadora de texto que permite seguir operando con el resultado anterior. Por ejemplo: 5 / 2 = 2.5 y luego 2.5 + 6 = 8.5.

Consejo de cierre del curso: mañana llega el primer gran proyecto final (Blackjack). Duerme bien. Pon una alarma para empezar a descansar, no solo para despertar, y evita las pantallas una o dos horas antes de dormir.

Prerequisito general: funciones con parámetros (Día 8), diccionarios (Día 9), while (Día 6) y float() (Día 2).


1. Funciones con salida: return

(Fuente: 073 - Functions with Outputs.md)

Prerequisito: funciones con parámetros (Día 8).

🎯 Objetivo de aprendizaje

  • Escribir funciones que devuelven un valor con return.
  • Explicar la diferencia entre imprimir (print) y devolver (return).
  • Encadenar funciones: usar la salida de una como entrada de otra.

🧠 ¿Qué aprenderemos?

  • La palabra clave return.
  • "La salida reemplaza la llamada".
  • El método .title().
  • print frente a return.

📖 Explicación conceptual

Python
def mi_funcion():
    resultado = 3 * 2
    return resultado

salida = mi_funcion()   # salida vale 6

La idea clave del curso: cuando la función termina, lo que va después de return reemplaza el lugar donde se llamó la función. Es como si mi_funcion() se convirtiera en 6.

Analogía del curso: una máquina que recibe botellas vacías (entrada), hace un proceso y entrega botellas llenas de leche (salida).

Ya habías usado funciones con salida: len("Angela") devuelve 6, y por eso puedes escribir cantidad = len("Angela").

El método .title() (el curso lo encuentra buscando "cómo convertir un string a Title Case en Python" en Stack Overflow): pone en mayúscula la primera letra de cada palabra y el resto en minúscula.

Python
"aNgElA".title()   # "Angela"

🔎 Ejemplo explicado: formatear un nombre

Python
def format_name(f_name, l_name):
    formatted_f_name = f_name.title()
    formatted_l_name = l_name.title()
    return f"{formatted_f_name} {formatted_l_name}"

formatted_string = format_name("aNgElA", "YU")
print(formatted_string)          # Angela Yu
print(format_name("sara", "RÍOS"))   # también se puede usar directamente dentro de print
  • Qué problema resuelve: unifica nombres escritos de cualquier forma.
  • Por qué return y no print: con return, quien llama a la función decide qué hacer con el resultado: imprimirlo, guardarlo, compararlo o pasarlo a otra función.

print frente a return (ejemplo del curso):

Python
def function_1(text):
    return text + text          # "eco"

def function_2(text):
    return text.title()

output = function_2(function_1("hola"))
print(output)                   # Holahola

La salida de function_1 se convierte en la entrada de function_2. Esto solo es posible porque ambas usan return. Si function_1 hiciera print en vez de return, function_2 no recibiría nada útil.

💡 Recomendación del curso: ejecuta este código en Thonny, paso a paso, para ver cómo la llamada "se reemplaza" por su resultado.

⚠️ Errores frecuentes

1. Imprimir en lugar de devolver

  • Qué ocurre: def doble(x): print(x * 2) y luego y = doble(4) hacen que y valga None.
  • Por qué ocurre: una función sin return devuelve None ("nada").
  • Cómo solucionarlo: usa return x * 2.

2. Llamar la función y no usar el resultado

  • Qué ocurre: format_name("ana", "paz") en una línea sola no muestra nada. El resultado se calcula y se pierde.
  • Cómo solucionarlo: guárdalo en una variable o imprímelo.

3. Olvidar los paréntesis de .title

  • Qué ocurre: se imprime algo como <built-in method title ...>.

📝 Ejercicio original del curso: format_name

Enunciado:

  1. Crea format_name(f_name, l_name).
  2. Convierte ambos nombres a formato título.
  3. Primero imprime el resultado; después cámbialo para que lo devuelva, y úsalo guardándolo en una variable y también directamente dentro de print.

🔍 Antes de programar

  • ¿Qué recibe la función? ¿Qué debe entregar?
  • ¿Cómo buscarías en internet un método para poner mayúsculas iniciales?

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: area_rectangulo(base, altura) devuelve el área. Úsala para calcular el área total de dos habitaciones sumando dos llamadas.
  • 🟡 Reto 2: es_par(n) devuelve True o False. Úsala dentro de un if: if es_par(numero):.
  • 🟠 Reto 3: encadena tres funciones: limpiar(texto), que quita espacios con .strip(); a_titulo(texto); y agregar_saludo(texto), que antepone "Hola, ". Llama agregar_saludo(a_titulo(limpiar(" ana maría "))).
  • 🔴 Reto 4: pensamiento computacional. "maría de la cruz".title() da "María De La Cruz", pero en español las partículas "de", "la" y "del" suelen ir en minúscula. Diseña una función formatear_nombre_es(nombre) que respete esa convención. (Pista: .split() para separar las palabras, un for y una lista de partículas.)

🧩 Comprueba lo aprendido: Tema 1

  • Conceptual: explica con tus palabras la frase "la salida reemplaza la llamada".
  • Predicción: ¿qué imprime este código?
Python
  def f(x):
      return x + 1
  print(f(f(3)))
  • Depuración: ¿por qué este código imprime None? Corrígelo:
Python
  def cuadrado(n):
      print(n * n)
  resultado = cuadrado(5)
  print(resultado)

Evidencia: Reto 4 con al menos 3 nombres de prueba.


2. Varios return y retorno anticipado

(Fuente: 074 - Multiple return values.md)

🎯 Objetivo de aprendizaje

  • Comprender que return termina la función de inmediato.
  • Usar un retorno anticipado para validar las entradas.

📖 Explicación conceptual

return termina la función. Todo lo que esté después, dentro del mismo bloque, no se ejecuta:

Python
def ejemplo():
    return "listo"
    print("Esto nunca se imprime")

Varios return en una función. Sirven para salir temprano cuando algo no está bien:

Python
def format_name(f_name, l_name):
    if f_name == "" or l_name == "":
        return "No ingresaste datos válidos."
    formatted_f_name = f_name.title()
    formatted_l_name = l_name.title()
    return f"{formatted_f_name} {formatted_l_name}"

print(format_name(input("¿Tu nombre? "), input("¿Tu apellido? ")))
  • Un return vacío (sin nada después) también termina la función y devuelve None. El curso lo muestra, pero recomienda devolver un mensaje útil que explique qué pasó.

🛠️ Nota técnica: el título original de la lección es "Multiple return values" (múltiples valores de retorno), pero lo que enseña son múltiples sentencias return. Son cosas distintas: en Python, una función también puede devolver varios valores a la vez (return a, b), algo que no se trata en esta lección. Lo verás como extensión en el Reto 4.

⚠️ Errores frecuentes

  • Código "muerto" después del return: escribir instrucciones después del return pensando que se ejecutarán. Algunos editores las muestran en gris.
  • Olvidar un camino sin return: si solo hay return dentro de un if, cuando la condición es falsa la función devuelve None.

📝 Ejercicio original del curso: validar entradas vacías

Enunciado: modifica format_name para que, si el nombre o el apellido llegan vacíos, termine de inmediato con un mensaje en lugar de seguir procesando. Resultado esperado: con entradas vacías se imprime el mensaje de error; con entradas válidas, el nombre formateado.

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: desempeno(nota) devuelve "Superior", "Alto", "Básico" o "Bajo" usando varios return (uno por rango, sin elif). Compárala con la versión con if/elif/else del Día 3.
  • 🟡 Reto 2: agrégale a desempeno un retorno anticipado si la nota está fuera del rango de 1.0 a 5.0.
  • 🟠 Reto 3: puede_votar(edad, tiene_documento) con retornos anticipados para cada requisito que no se cumpla. Cada return debe decir qué falta.
  • 🔴 Reto 4: investiga cómo devolver dos valores: return minimo, maximo, y cómo recibirlos: mn, mx = min_max(lista). Crea min_max(lista) sin usar min() ni max().

🧩 Comprueba lo aprendido: Tema 2

  • Predicción: ¿qué imprime este código?
Python
  def g(x):
      if x > 0:
          return "positivo"
      return "no positivo"
      print("fin")
  print(g(5))
  print(g(-1))
  • Depuración: def signo(n): con if n > 0: return "+" y elif n < 0: return "-". ¿Qué devuelve signo(0)? ¿Cómo lo corriges?

3. Docstrings: documentar tus funciones

(Fuente: 075 - Docstrings.md)

🎯 Objetivo de aprendizaje

  • Documentar funciones con docstrings.
  • Distinguir un docstring de un comentario.

📖 Explicación conceptual

Cuando pasas el cursor sobre len(), el editor muestra "Return the number of items in a container". Esa es su documentación. Tus funciones pueden tener la suya con un docstring:

Python
def format_name(f_name, l_name):
    """Recibe un nombre y un apellido y devuelve
    el nombre completo en formato título."""
    ...
  • Va en la primera línea dentro de la función.
  • Se escribe entre tres comillas """ y puede ocupar varias líneas.
  • Aparece como ayuda cuando alguien llama la función. También puedes verla con help(format_name).

¿Y como comentario de varias líneas? Un string de triple comilla "suelto" funciona como comentario, pero la guía oficial de Python recomienda no usarlo así, porque se confunde con el código. Para comentar varias líneas: selecciónalas y presiona Ctrl + / (Windows) o Cmd + / (Mac), que agrega un # a cada una.

Herramienta Para qué sirve
# comentario Explicar el cómo o el por qué de una línea
"""docstring""" Explicar qué hace una función, qué recibe y qué devuelve

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: agrega docstrings a todas las funciones de los Temas 1 y 2 y comprueba que aparecen al llamarlas.
  • 🟡 Reto 2: usa help(tu_funcion) en la consola de Python y observa el resultado.
  • 🟠 Reto 3: escribe docstrings que digan qué recibe, qué devuelve y un ejemplo de uso.
  • 🔴 Reto 4: intercambia código con un compañero sin docstrings y trata de adivinar qué hace cada función. Luego escribe los docstrings de sus funciones. ¿Qué información fue más difícil de deducir?

4. Funciones como valores

(Fuente: 076 - The Calculator Project.md, primera parte)

Prerequisito: diccionarios (Día 9).

🎯 Objetivo de aprendizaje

  • Guardar una función en una variable o en un diccionario, sin llamarla.
  • Llamar una función a partir de una clave.

📖 Explicación conceptual

Python
def add(n1, n2):
    return n1 + n2

my_favourite_operation = add        # SIN paréntesis: se guarda la función
print(my_favourite_operation(2, 3)) # 5 → CON paréntesis: se ejecuta
Escritura Significado
add La función en sí, como una "receta guardada"
add(2, 3) Ejecutar la función con 2 y 3

Un diccionario de funciones. Cada operador se asocia a su función:

Python
operations = {
    "+": add,
    "-": subtract,
    "*": multiply,
    "/": divide,
}
print(operations["*"](4, 8))   # 32

Lectura paso a paso: operations["*"] → la función multiply; luego (4, 8) → se ejecuta con 4 y 8 → 32.

¿Por qué es útil? Porque el símbolo que escribe el usuario ("*") se usa directamente como clave. No hace falta un if/elif por cada operación.

📝 Ejercicio original del curso: tres retos previos

  1. Escribe subtract, multiply y divide, cada una con n1 y n2, siguiendo el modelo de add.
  2. Guárdalas en un diccionario operations con las claves "+", "-", "*" y "/".
  3. Usa el diccionario para multiplicar 4 × 8. Resultado esperado: 32.

🔍 Antes de programar

  • ¿Por qué no deben llevar paréntesis las funciones cuando las guardas en el diccionario?
  • Si operations["*"] "es" multiply, ¿qué le falta para ejecutarse?

⚠️ Errores frecuentes

  • Poner paréntesis al guardar: {"+": add()} produce TypeError: missing 2 required positional arguments, porque intenta ejecutar la función en ese momento.
  • Olvidar los paréntesis al usar: print(operations["*"]) muestra <function multiply ...>.
  • Clave inexistente: operations["%"] produce KeyError: '%' (verificado).

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: agrega la potencia ("**") y la división entera ("//") al diccionario.
  • 🟡 Reto 2: recorre el diccionario con un for y muestra el resultado de aplicar cada operación a 12 y 4.
  • 🟠 Reto 3: crea un diccionario de funciones para un "traductor" de texto: "mayus" → una función que pone todo en mayúsculas, "minus" → en minúsculas, "titulo" → en formato título. El usuario elige la opción y escribe el texto.
  • 🔴 Reto 4: rehaz la lógica de Piedra, Papel o Tijera (Día 4) con un diccionario que asocie cada figura con la figura a la que le gana. ¿Se simplifica el código?

5. 🚀 Proyecto del día: la Calculadora

(Fuente: 076 - The Calculator Project.md, proyecto oficial del curso original)

Requisitos funcionales (del curso)

  1. Pedir el primer número.
  2. Mostrar los operadores disponibles (recorriendo el diccionario) y pedir uno.
  3. Pedir el siguiente número.
  4. Calcular con el diccionario de funciones y mostrar la ecuación completa: 5.0 * 3.0 = 15.0.
  5. Preguntar: y para seguir calculando con el resultado, o n para empezar un cálculo nuevo.
  6. Con y, el resultado anterior pasa a ser el primer número y se piden un operador y un segundo número.
  7. Con n, se "limpia" la pantalla y se empieza de nuevo, mostrando el logo.

Restricciones técnicas

Funciones con return, un diccionario de funciones, float(), while y f-strings.

🔍 Antes de programar

  • ¿Por qué el curso convierte los números con float() y no con int()? (Pista: la división.)
  • ¿Qué pasa si no conviertes? ("3" + "3" da "33".)
  • ¿Qué parte del programa se repite con y? ¿Y qué parte con n?
  • Dibuja el diagrama de flujo: dos "ciclos" distintos, uno para seguir acumulando y otro para reiniciar.

Construcción paso a paso (según la solución del curso)

Versión 1: un solo cálculo. Entradas → operations[operation_symbol](num1, num2) → imprimir la ecuación.

Versión 2: seguir con el resultado. Un while controlado por la bandera should_accumulate. Con y, num1 = answer. Ojo: la primera entrada de num1 debe ir fuera del while, para que no se vuelva a pedir en cada vuelta.

Versión 3: reiniciar. El curso envuelve todo en una función calculator() y, con n, la función se llama a sí misma. Esto se llama recursión. El curso aclara que usar otro while externo en lugar de recursión es "perfectamente aceptable".

Estrategia para reiniciar Ventaja Desventaja
Recursión: calculator() dentro de calculator() Pocas líneas Cada reinicio agrega una llamada "pendiente". Python tiene un límite de unas 1000 llamadas anidadas (RecursionError)
Un while externo Sin límite de reinicios, y más fácil de seguir para quien empieza Un nivel más de sangría

Versión 4: logo. import art y print(art.logo) al inicio de calculator(). El archivo art.py no está incluido entre los materiales suministrados: crea tu propio logo.

Pruebas

Entradas Resultado esperado
5, *, 3 5.0 * 3.0 = 15.0
(y) +, 5 15.0 + 5.0 = 20.0
(n) 5, /, 2 5.0 / 2.0 = 2.5
5, /, 0 ⚠️ ZeroDivisionError en la versión del curso (verificado)
5, %, 2 ⚠️ KeyError: '%' en la versión del curso (verificado)

🛠️ Nota técnica: la solución del curso no valida la división entre cero ni los operadores inexistentes. Mejoras propuestas:

  • En divide, usa un retorno anticipado (Tema 2) si n2 == 0 y devuelve un mensaje.
  • Antes de calcular, verifica que el operador exista con if operation_symbol in operations:.
  • Una entrada no numérica produce ValueError. El manejo de excepciones llega más adelante en el curso.

🧪 Prueba y depuración

Este código tiene cuatro errores:

Python
operations = {"+": add(), "-": subtract, "*": multiply, "/": divide}

def calculator():
    should_accumulate = True
    while should_accumulate:
        num1 = float(input("Primer número: "))
        for symbol in operations:
            print(symbol)
        operation_symbol = input("Elige una operación: ")
        num2 = input("Siguiente número: ")
        answer = operations[operation_symbol](num1, num2)
        print(f"{num1} {operation_symbol} {num2} = {answer}")
        choice = input(f"'y' para seguir con {answer}, 'n' para nuevo: ")
        if choice == "y":
            num1 = answer
        else:
            should_accumulate = False
            calculator()

(Pistas: una función que se ejecuta al guardarla, un número que se queda como texto, un num1 que se vuelve a pedir en cada vuelta y… ¿se llama calculator() alguna vez desde fuera?)

⭐ Extensión del proyecto

  • Guardar un historial de operaciones en una lista y mostrarlo al salir.
  • Agregar una opción q para salir del programa por completo.
  • Redondear los resultados a un número de decimales elegido por el usuario.

6. 🌟 Proyecto extra: Conversor de Unidades

Situación

En Física y Química del grado 10 hay que convertir unidades todo el tiempo. Vas a construir un conversor que use funciones con return guardadas en un diccionario.

Requisitos

  1. Funciones con return y docstring, por ejemplo:
    • c_a_f(c): Celsius a Fahrenheit, con la fórmula c * 9 / 5 + 32.
    • f_a_c(f): Fahrenheit a Celsius.
    • km_a_mi(km): kilómetros a millas, dividiendo entre 1.609.
    • kg_a_lb(kg): kilogramos a libras, multiplicando por 2.2046.
  2. Un diccionario conversiones con una clave legible por función ("C->F", …) cuyo valor sea la función.
  3. Un menú generado con un for sobre el diccionario.
  4. Validar la opción con in y repetir hasta que el usuario escriba salir.

Casos de prueba

Conversión Entrada Resultado esperado
C->F 100 212.0
F->C 32 0.0
C->F -40 -40.0

⭐ Extensión

Haz que cada conversión funcione en ambos sentidos reutilizando funciones. Por ejemplo, f_a_c puede definirse a partir de la fórmula inversa. ¿Qué pruebas garantizan que una conversión y su inversa son coherentes?


7. 🏆 Proyecto integrador del Día 10: Informe Académico 3.0

Proyecto integrador creado para esta adaptación. Es la tercera versión del proyecto de notas: Día 2 (cálculo), Día 3 (decisiones) y ahora Día 10 (funciones con return). Muestra cómo un programa mejora cuando se organiza en funciones.

Situación problema

El Informe Académico 2.0 (Día 3) funcionaba, pero todo estaba en un solo bloque largo. La coordinación quiere procesar varios estudiantes y reutilizar los cálculos en otros programas.

Pregunta orientadora

¿Cómo dividir un programa en funciones pequeñas, cada una con una sola tarea, que devuelvan resultados combinables?

Requerimientos

  1. Funciones con return y docstring:
    • nota_valida(nota) → True/False.
    • calcular_definitiva(talleres, proyecto, evaluacion) → la nota redondeada a 1 decimal, con los pesos 30/40/30. Retorno anticipado con un mensaje si alguna nota es inválida.
    • desempeno(nota) → "Superior", "Alto", "Básico" o "Bajo".
    • pierde_por_fallas(clases, fallas) → True si las fallas superan el 25 %.
    • generar_informe(nombre, definitiva, desempeno, pierde) → un string de varias líneas (no lo imprime: lo devuelve).
  2. Un programa principal que procese estudiantes en un while hasta que se escriba fin, y guarde cada informe en un diccionario {nombre: informe}.
  3. Al final, imprimir todos los informes y el promedio del grupo.

Restricciones técnicas

Días 1 a 10. Ninguna función, salvo el programa principal, puede usar print: todas deben devolver sus resultados.

Casos de prueba (valores verificados en el Día 3)

Talleres Proyecto Evaluación Clases/Fallas Definitiva Desempeño ¿Pierde por fallas?
4.2 4.8 3.6 40/2 4.3 Alto No
2.9 3.0 3.0 40/4 3.0 Básico No
4.2 4.8 3.6 40/12 4.3 Alto Sí
5.5 4.0 4.0 — Mensaje de nota inválida — —

Entregables

Código con todas las funciones documentadas, tabla de pruebas y una comparación escrita entre las versiones 2.0 y 3.0: ¿qué es más fácil de modificar ahora?

Criterios técnicos

  • Cada función hace una sola cosa y se puede probar sola, por ejemplo print(desempeno(4.6)).
  • No hay print dentro de las funciones auxiliares.
  • Todos los casos de prueba producen el resultado esperado.

8. 🤖 Programar con apoyo de IA

El curso encuentra .title() buscando en Stack Overflow. Una IA daría la misma respuesta más rápido, y la regla sigue siendo la misma: entender antes de usar.

Actividad: el caso que la IA olvida. Pide a una IA: "Escribe una calculadora en Python con funciones y un diccionario". Luego:

  1. Pruébala con 5 / 0 y con el operador %.
  2. Si falla, pídele que lo corrija y explique su solución.
  3. Revisa si usó recursión o while para reiniciar. Pregúntale por las ventajas y desventajas de cada opción y compara su respuesta con la tabla de la Sección 5.

9. 🛠️ Correcciones técnicas al material original

Archivo Afirmación o comportamiento del curso Observación Tratamiento
074 Título "Multiple return values" Enseña múltiples sentencias return, no el retorno de varios valores (return a, b) Nota técnica y Reto 4 del Tema 2
073 title() se llama "función" Es un método de los strings Tema 1
073 .title() como solución universal para nombres En español pone en mayúscula las partículas ("De La Cruz") Reto 4 del Tema 1
076 La calculadora no valida entradas División entre 0 → ZeroDivisionError; operador inexistente → KeyError (verificado) Nota técnica y pruebas del proyecto
076 Reinicio por recursión Cada reinicio agrega una llamada; el límite de Python es de unas 1000 llamadas anidadas (RecursionError) Tabla comparativa en la Sección 5
076 Archivo art.py y archivo inicial No están incluidos entre los materiales suministrados Se pide crearlos

10. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Objetivos: calculadora 072 Sección 0 — — Sección 5
return, .title(), print frente a return, funciones encadenadas 073 Tema 1 format_name Retos 1–4 del Tema 1 (nombres en español) Secciones 5, 6 y 7
Varios return, retorno anticipado 074 Tema 2 Validar entradas vacías Retos 1–4 del Tema 2 (min_max) Sección 7
Docstrings 075 Tema 3 Agregar docstrings Retos 1–4 del Tema 3 Secciones 6 y 7
Funciones como valores, diccionario de funciones 076 Tema 4 Las 3 funciones, el diccionario y 4 × 8 Retos 1–4 del Tema 4 Secciones 5 y 6
Calculadora: acumular, reiniciar, recursión 076 Integración Proyecto oficial Depuración con 4 errores, validaciones y extensiones Sección 5
Consejos para dormir bien 077 Sección 0 — — —
(No existe en el curso original) — — — Conversor de Unidades Sección 6
(No existe en el curso original) — — — Informe Académico 3.0 Sección 7

11. 📦 Evidencias de aprendizaje del Día 10

  • Calculadora funcionando, con la tabla de pruebas y al menos una de las validaciones propuestas.
  • Explicación escrita de "la salida reemplaza la llamada", con un ejemplo propio.
  • Funciones con docstrings (Tema 3).
  • Proyecto extra (Conversor) o integrador (Informe 3.0).
  • Cuaderno de errores: None por imprimir en lugar de devolver, TypeError por guardar una función con paréntesis, KeyError por un operador inexistente, ZeroDivisionError y RecursionError.