Funciones: Taller Integrador
Ya viste def, parámetros, valores por defecto, return y scope como tema separado. Este taller no enseña nada nuevo: te da 11 problemas cortos más un reto final para que combines funciones con todo lo que ya sabías (condicionales, bucles, listas) resolviendo problemas de verdad — la misma idea que el taller de repaso anterior, pero ahora todo pasa adentro de funciones.
Bienvenido
Este taller es la práctica integradora de Funciones junto con todo lo anterior: Variables, Condicionales, Bucles y el resto de guías de POO. No repite la teoría de ninguna — si algo no te suena, es el momento de volver a repasarlo antes de seguir.
Este taller asume que ya completaste Funciones en Python y las guías previas. Ningún ejercicio necesita recursión, *args/**kwargs, ni indexado de listas (lista[0]) o métodos como .append() — nada de eso se explicó todavía, y no hace falta: alcanza con for elemento in lista, tal como en el taller anterior.
Cada ejercicio trae un editor vacío: el enunciado te dice qué función tenés que escribir, y vos escribís el código Python de cero. Presiona ▶ Ejecutar para correrlo de verdad en tu navegador con Pyodide (Python real compilado a WebAssembly). La primera ejecución tarda unos segundos porque descarga el intérprete.
En este taller, copiar y pegar código en los editores está deshabilitado (incluido arrastrar y soltar). La idea es que practiques escribiendo la sintaxis vos mismo, no que la traigas de otro lado.
🧩 Integrador
Cada bloque mezcla funciones con condicionales, bucles y listas.
🔁 Funciones que se llaman
La sección 3 usa el resultado de una función dentro de otra.
🎯 Reto final
Un problema más largo que se resuelve organizando el código en varias funciones, no en un solo bloque.
Zona de pruebas libres
Este bloque queda disponible durante todo el taller. Usalo en cualquier momento para probar una idea suelta, revisar cómo se comporta una función, o experimentar algo que se te ocurra a mitad de un ejercicio — sin desordenar los bloques numerados.
1. Funciones que calculan y deciden
Cuatro funciones que reciben datos, deciden algo con if/elif/else y devuelven un resultado con return.
Escribe una función es_bisiesto(anio) que devuelva True o False. Un año es bisiesto si es divisible entre 4, salvo que también sea divisible entre 100 — en ese caso, tiene que ser divisible entre 400 para seguir siendo bisiesto (por ejemplo, 2000 fue bisiesto, pero 1900 no). Prueba tu función con print(es_bisiesto(2024)) y print(es_bisiesto(1900)).
Escribe una función a_dolares(bolivianos, tasa=6.96) con tasa como parámetro con valor por defecto (el tipo de cambio oficial). Debe devolver el monto convertido a dólares, redondeado a 2 decimales con round(). Pruébala una vez sin pasar la tasa, print(a_dolares(500)), y otra vez pasando una tasa distinta, print(a_dolares(500, 7.10)).
Escribe una función rectangulo(base, altura) que devuelva dos valores con un solo return: el área (base * altura) y el perímetro (2 * (base + altura)). Llámala desempaquetando el resultado en dos variables, area, perimetro = rectangulo(4, 6), e imprime ambas.
Escribe una función clasificar_imc(peso, altura) que calcule el índice de masa corporal (imc = peso / altura ** 2, con altura en metros) y devuelva un texto según el resultado, usando if/elif/else adentro de la función: "Bajo peso" si imc < 18.5, "Normal" si está entre 18.5 y 25 (sin incluir 25), "Sobrepeso" si está entre 25 y 30 (sin incluir 30), o "Obesidad" si imc >= 30. Prueba con print(clasificar_imc(70, 1.75)).
2. Funciones con listas
Cuatro funciones que reciben una lista como parámetro y la recorren con for elemento in lista por dentro. Ninguna necesita indexado ni .append().
Escribe una función contar_pares(lista) que devuelva cuántos elementos de la lista son pares. Pruébala con print(contar_pares([4, 7, 10, 15, 22, 3, 8])).
Escribe una función promedio_lista(lista) que devuelva el promedio de sus elementos (suma dividida entre len(lista)). Vas a reutilizar esta misma idea en el reto final, así que consérvala bien resuelta. Pruébala con print(promedio_lista([15, 8, 20, 3, 12])).
Escribe una función buscar_mayor(lista) que devuelva el valor más grande, sin usar max(). Como no hay indexado, arranca con mayor = None antes del for, y dentro del bucle actualiza mayor cuando mayor is None (todavía no viste ningún elemento) o el elemento actual es mayor que mayor. Pruébala con print(buscar_mayor([19, 23, 18, 31, 22, 27])).
Escribe una función contiene_negativos(lista) que devuelva True apenas encuentre un elemento menor a 0 — con un return True dentro del propio for, sin esperar a que termine de recorrer toda la lista. Si el bucle termina sin encontrar ninguno, la función debe devolver False al final. Pruébala con print(contiene_negativos([5, 8, -1, 12])) y print(contiene_negativos([5, 8, 1, 12])).
Un return dentro de un bucle termina la función entera de inmediato, no solo esa vuelta del for — por eso alcanza con un return True apenas se cumple la condición, sin necesitar break ni una variable auxiliar.
3. Funciones que llaman a otras funciones
Tres problemas donde una función usa el resultado de otra, en vez de repetir su lógica — la razón principal por la que conviene empaquetar código en funciones.
Escribe una función es_primo(n) (igual que en el taller anterior, pero ahora como función reutilizable). Luego, con un for que recorra range(2, 30), llama a es_primo() con cada número e imprime solo los que son primos. La ventaja frente a escribir la lógica de nuevo: si mañana necesitas primos en otro rango, no reescribes nada, solo volvés a llamar la función.
Escribe una función factorial(n) (igual que en el taller anterior). Luego escribe combinaciones(n, k) que devuelva factorial(n) // (factorial(k) * factorial(n - k)) — llamando a factorial() tres veces adentro, sin repetir su lógica. Prueba con print(combinaciones(5, 2)) (debería dar 10).
Escribe una función comision(monto, categoria="regular") que devuelva el monto de la comisión según categoria: 5% si es "regular", 10% si es "premium", 2% para cualquier otro valor. Luego escribe total_con_comision(monto, categoria="regular"), que llame a comision() y devuelva monto + comision(monto, categoria). Prueba con print(total_con_comision(1000)) y print(total_con_comision(1000, "premium")).
Reto final: Boletín de notas, organizado en funciones
El mismo tipo de problema que el reto del taller anterior — pero esta vez la consigna es que no lo resuelvas en un solo bloque de código: tenés que separar la lógica en funciones con nombre, y llamarlas desde abajo.
Escribe en el editor esta lista (notas sobre 20, aprobado desde 11): notas = [15, 8, 20, 3, 12, 18, 6, 10, 19, 2]
- 1.
promedio(lista)— devuelve el promedio de la lista (podés reutilizar tu solución del ejercicio 2.2). - 2.
contar_aprobados(lista)— devuelve cuántas notas son mayores o iguales a 11. - 3.
nota_mas_alta(lista)— devuelve la nota más alta, sin usarmax()(podés reutilizar la idea del ejercicio 2.3). - 4.
clasificar_rendimiento(promedio)— recibe un número (no la lista) y devuelve el texto "Buen rendimiento general" si es mayor o igual a 14, "Rendimiento regular" si está entre 11 y 14, o "Rendimiento bajo" si es menor a 11.
Llamando a las cuatro funciones (no repitiendo su lógica suelta): el promedio con 2 decimales, la cantidad de aprobados, la nota más alta, y el mensaje de rendimiento que corresponde según ese promedio.
Cheat Sheet del taller
| Herramienta | Para qué la usaste hoy |
|---|---|
def nombre(param=valor): ... | Parámetro con valor por defecto, opcional al llamar. |
return a, b | Devolver varios valores a la vez, para desempaquetar en dos variables. |
if/elif/else dentro de una función | Decidir qué devolver según el dato recibido. |
for elemento in lista dentro de una función | Recorrer una lista que llega como parámetro. |
mayor = None + actualizar en el for | Encontrar el máximo de una lista sin indexado ni max(). |
return dentro de un bucle | Cortar la función entera apenas se cumple una condición. |
| Una función que llama a otra | Reutilizar lógica ya resuelta (factorial() adentro de combinaciones()). |
| Separar un problema en funciones con nombre | Organizar un programa más grande en piezas que se prueban por separado. |
¿Sabías que...?
🧱 El primer paso hacia los objetos
Separar el reto final en promedio(), contar_aprobados(), etc. es exactamente la misma idea que vas a usar al escribir tus primeras clases: un método es, ni más ni menos, una función que vive adentro de una clase.
🔁 Funciones que se llaman a sí mismas
factorial() se puede escribir de otra forma, haciendo que la función se llame a sí misma en vez de usar un for — se llama recursión. Todavía no la viste en este curso, pero es una técnica muy usada y la vas a encontrar más adelante.
🏆 Inspirado en el banco de la UAB
Varios de estos problemas están pensados en el mismo espíritu que el banco de preguntas de la Competencia de Programación UAB, adaptados para practicar funciones específicamente.