Clase 7¶
¿Por qué necesitamos funciones?¶
En las clases anteriores, los programas crecieron en complejidad: ciclos, listas, validaciones, menús. Con el tiempo, aparece un problema nuevo: el código se repite.
Suponga que se necesita calcular el promedio de tres grupos de estudiantes distintos:
notas_a = [85, 90, 72, 88, 95]
suma_a = sum(notas_a)
promedio_a = suma_a / len(notas_a)
print(f"Grupo A - Promedio: {promedio_a:.1f}")
notas_b = [78, 82, 69, 91, 74]
suma_b = sum(notas_b)
promedio_b = suma_b / len(notas_b)
print(f"Grupo B - Promedio: {promedio_b:.1f}")
notas_c = [95, 88, 76, 80, 93]
suma_c = sum(notas_c)
promedio_c = suma_c / len(notas_c)
print(f"Grupo C - Promedio: {promedio_c:.1f}")
La lógica es exactamente la misma en los tres bloques. Si después se necesita cambiar el formato de salida o agregar una condición, habría que modificar el código en tres lugares distintos.
¿Qué pasa cuando hay diez grupos?
Con diez grupos, habría que duplicar la lógica diez veces. Cualquier corrección exigiría cambiar el código en diez lugares. Un solo olvido introduce un error difícil de encontrar.
Las funciones resuelven este problema.
Una función es un bloque de código con nombre que realiza una tarea específica y puede ejecutarse todas las veces que se necesite, desde cualquier parte del programa.
Con una función, el ejemplo anterior se convierte en:
def calcular_promedio(notas):
return sum(notas) / len(notas)
notas_a = [85, 90, 72, 88, 95]
notas_b = [78, 82, 69, 91, 74]
notas_c = [95, 88, 76, 80, 93]
print(f"Grupo A - Promedio: {calcular_promedio(notas_a):.1f}")
print(f"Grupo B - Promedio: {calcular_promedio(notas_b):.1f}")
print(f"Grupo C - Promedio: {calcular_promedio(notas_c):.1f}")
La lógica se escribe una sola vez y se reutiliza tres veces. Si se necesita cambiar algo, el cambio se hace en un único lugar.
Idea central
Una función separa qué se quiere hacer (calcular un promedio) de cuándo y con qué datos hacerlo. El programador define la lógica una sola vez; la función se encarga de aplicarla cuantas veces sea necesario.
Definición y uso de funciones¶
Sintaxis básica¶
Para crear una función en Python se usa la palabra reservada def, seguida del nombre de la función y paréntesis:
defindica que se está definiendo una función.saludares el nombre. Los paréntesis()son obligatorios, aunque la función no reciba datos.- Todo el código indentado dentro de la función forma su cuerpo. Se ejecuta cada vez que la función es llamada.
Para ejecutar la función, se escribe su nombre seguido de paréntesis:
- Primera llamada: imprime
¡Hola mundo! - Segunda llamada: imprime
¡Hola mundo!de nuevo.
Definir antes de llamar
La función debe definirse antes de ser llamada.
Si se intenta llamar una función que aún no existe en el código, Python genera un NameError.
- Error: aún no está definida
Flujo de ejecución¶
Cuando Python encuentra una llamada a una función, pausa el código actual, ejecuta el cuerpo de la función completo y luego retoma desde donde se detuvo.
print("Antes de la función") # (1)!
def despedirse():
print("¡Hasta luego!")
despedirse() # (2)!
print("Después de la función") # (3)!
Antes de la función¡Hasta luego!Después de la función
Nombre de una función¶
El nombre de una función debe describir claramente qué hace.
Por convención en Python se usa snake_case: palabras en minúscula separadas por guion bajo.
Las funciones son verbos
Un buen nombre de función generalmente comienza con un verbo: calcular, mostrar, verificar, obtener, imprimir.
Esto refleja que las funciones hacen algo.
Parámetros y argumentos¶
Una función puede recibir datos desde afuera para trabajar con ellos. Estos datos se definen como parámetros en la declaración de la función y se pasan como argumentos al llamarla.
Función con un parámetro¶
nombrees el parámetro: una variable local que recibe el valor que se pase al llamar la función.
Al llamar la función, se pasa el argumento entre paréntesis:
saludar_estudiante("Ana") # (1)!
saludar_estudiante("Carlos") # (2)!
saludar_estudiante("Sofía") # (3)!
¡Hola Ana! Bienvenido.¡Hola Carlos! Bienvenido.¡Hola Sofía! Bienvenido.
Función con varios parámetros¶
Una función puede recibir más de un parámetro, separados por comas.
def mostrar_nota(nombre, nota): # (1)!
if nota >= 70:
estado = "Aprobado"
else:
estado = "Reprobado"
print(f"{nombre}: {nota} — {estado}")
- La función recibe dos datos: el nombre del estudiante y su nota.
Ana: 92 — AprobadoLuis: 65 — ReprobadoMaría: 78 — Aprobado
El orden de los argumentos importa
Los argumentos se asignan a los parámetros en el mismo orden en que se declaran.
Llamar mostrar_nota(92, "Ana") causaría un error porque intentaría comparar "Ana" >= 70.
Parámetros con valor por defecto¶
Un parámetro puede tener un valor por defecto que se usa cuando el argumento no se proporciona al llamar la función.
- Si no se pasa un segundo argumento,
saludotomará el valor"¡Hola"por defecto.
¡Hola, Ana!¡Buenos días, Luis!
Los parámetros con defecto van al final
En Python, los parámetros con valor por defecto siempre deben ir después de los parámetros sin valor por defecto. def f(a="x", b) generaría un error de sintaxis.
Retorno de valores¶
Hasta ahora, las funciones imprimen resultados directamente. Sin embargo, muchas veces se necesita que la función devuelva un valor para que el programa pueda usarlo después.
La instrucción return devuelve un valor al lugar desde donde se llamó la función y la termina inmediatamente.
Función con return¶
- La función no imprime nada: devuelve el promedio calculado.
El valor devuelto puede guardarse en una variable o usarse directamente:
notas = [85, 90, 72, 88, 95]
promedio = calcular_promedio(notas) # (1)!
print(f"El promedio es: {promedio:.1f}") # (2)!
- El resultado de la función se guarda en
promedio. El promedio es: 86.0
También se puede usar directamente sin guardar:
- El valor de retorno se usa directamente dentro del f-string.
¿return o print?
Una función que usa print solo muestra el resultado en pantalla. No puede enviarse a otra función ni guardarse para usarlo después.
Una función que usa return devuelve el resultado para que el código que la llamó decida qué hacer con él. Esto la hace mucho más flexible y reutilizable.
La regla general: las funciones deben calcular y retornar. La tarea de imprimir queda fuera de la función, en el código principal.
Múltiples puntos de retorno¶
Una función puede tener más de un return, aunque solo se ejecutará el primero que se alcance.
def clasificar_nota(nota):
if nota >= 90:
return "Excelente"
elif nota >= 80:
return "Muy bueno"
elif nota >= 70:
return "Bueno"
else:
return "Debe mejorar"
print(clasificar_nota(95)) # (1)!
print(clasificar_nota(82)) # (2)!
print(clasificar_nota(61)) # (3)!
ExcelenteMuy buenoDebe mejorar
Funciones sin return¶
Si una función no tiene return (o tiene return sin valor), devuelve None implícitamente. None es el valor en Python que representa "ausencia de valor".
- La función se ejecuta e imprime
¡Hola!, pero no retorna ningún valor. None
Resumen: return en funciones
| Caso | Qué devuelve |
|---|---|
return valor |
El valor indicado |
return (sin valor) |
None |
Sin instrucción return |
None |
Alcance de variables¶
El alcance (o scope) de una variable define en qué partes del programa esa variable es accesible.
Variables locales¶
Una variable definida dentro de una función solo existe dentro de ella. Se crea cuando la función se ejecuta y se destruye cuando la función termina.
def calcular_area(base, altura):
area = base * altura # (1)!
return area
calcular_area(5, 3)
print(area) # (2)!
areaes una variable local: solo existe dentro decalcular_area.NameError: name 'area' is not defined. La variableareano existe fuera de la función.
Variables globales¶
Una variable definida fuera de todas las funciones es global y puede leerse desde cualquier función.
umbral_aprobacion = 70 # (1)!
def aprobo(nota):
return nota >= umbral_aprobacion # (2)!
print(aprobo(85)) # (3)!
print(aprobo(60)) # (4)!
umbral_aprobaciones una variable global: se define fuera de cualquier función.- La función puede leer la variable global directamente.
TrueFalse
Modificar variables globales dentro de funciones
En Python, leer una variable global dentro de una función está permitido. Pero modificarla requiere usar la palabra reservada global, lo cual no es una buena práctica.
La forma correcta es pasar los datos que la función necesita como parámetros y recibir los resultados a través de return.
Resumen de alcance¶
flowchart TD
subgraph Global["Ámbito global"]
VG["variable_global = 10"]
subgraph Funcion["Función mi_funcion(param)"]
VP["param → local"]
VL["variable_local → local"]
LG["Puede leer variable_global"]
end
end
Regla práctica
Los datos que una función necesita deben entrar como parámetros y los resultados deben salir como return. Las variables globales son para constantes o configuraciones que no cambian.
Descomposición de problemas y reutilización de código¶
Las funciones no solo evitan repetición: son la herramienta principal para dividir un problema complejo en partes manejables.
El principio de responsabilidad única¶
Cada función debe hacer una sola cosa y hacerla bien. Un programa bien diseñado es una colección de funciones pequeñas, cada una con una responsabilidad clara.
Suponga que se necesita un programa que analice las notas de un grupo: muestre el promedio, identifique al mejor estudiante y cuente cuántos aprobaron.
Sin funciones, todo estaría en un solo bloque difícil de leer y mantener:
# Sin funciones — difícil de leer y mantener
nombres = ["Ana", "Luis", "María", "Carlos", "Sofía"]
notas = [92, 78, 85, 65, 90]
suma = 0
for nota in notas:
suma += nota
promedio = suma / len(notas)
print(f"Promedio: {promedio:.1f}")
maximo = notas[0]
indice_max = 0
for i in range(1, len(notas)):
if notas[i] > maximo:
maximo = notas[i]
indice_max = i
print(f"Mejor estudiante: {nombres[indice_max]} con {maximo}")
aprobados = 0
for nota in notas:
if nota >= 70:
aprobados += 1
print(f"Aprobados: {aprobados}")
Con funciones, cada tarea queda aislada con un nombre claro:
def calcular_promedio(notas):
return sum(notas) / len(notas)
def encontrar_mejor(nombres, notas):
indice = notas.index(max(notas))
return nombres[indice], notas[indice]
def contar_aprobados(notas, umbral=70):
return sum(1 for nota in notas if nota >= umbral)
nombres = ["Ana", "Luis", "María", "Carlos", "Sofía"]
notas = [92, 78, 85, 65, 90]
print(f"Promedio: {calcular_promedio(notas):.1f}")
mejor_nombre, mejor_nota = encontrar_mejor(nombres, notas)
print(f"Mejor estudiante: {mejor_nombre} con {mejor_nota}")
print(f"Aprobados: {contar_aprobados(notas)}")
Ventajas de la descomposición
- Cada función puede probarse de forma independiente.
- Si hay un error, es más fácil localizarlo en una función pequeña que en un bloque largo.
- Cada función puede reutilizarse en otros programas o en otras partes del mismo programa.
Funciones que llaman a otras funciones¶
Las funciones pueden llamarse entre sí. Esto permite construir capas de abstracción: funciones complejas construidas sobre funciones simples.
def es_par(numero):
return numero % 2 == 0
def filtrar_pares(lista): # (1)!
pares = []
for numero in lista:
if es_par(numero): # (2)!
pares.append(numero)
return pares
numeros = [1, 4, 7, 8, 12, 15, 20]
print(filtrar_pares(numeros)) # (3)!
filtrar_paresdepende dees_parpara su lógica.- Cada número se verifica con
es_parantes de agregarlo. [4, 8, 12, 20]
Introducción a la recursividad¶
Hasta ahora, todas las funciones vistas resuelven su tarea usando ciclos o estructuras simples. Existe otro enfoque poderoso: una función que se llama a sí misma. Esto se llama recursividad.
La idea detrás de la recursividad¶
La recursividad es útil cuando un problema se puede expresar en términos de versiones más pequeñas del mismo problema.
Por ejemplo, el factorial de un número:
Pero también se puede expresar así:
Cada factorial se define en términos del factorial anterior. El problema se va reduciendo hasta llegar a un caso conocido: \(1! = 1\).
Caso base y caso recursivo¶
Toda función recursiva correcta tiene dos partes obligatorias:
| Parte | Descripción |
|---|---|
| Caso base | La condición que detiene la recursión. Sin esto, la función se llama a sí misma infinitamente. |
| Caso recursivo | La llamada a la propia función con un problema más pequeño. |
Factorial recursivo¶
- La función recibe el número
ndel que se quiere calcular el factorial. - Caso base: cuando
nllega a1, se retorna1directamente. Aquí se detiene la recursión. - Caso recursivo: el factorial de
nesnmultiplicado por el factorial den - 1.
1206
El proceso de ejecución para factorial(5) se puede visualizar así:
flowchart TD
A["factorial(5)"] --> B["5 × factorial(4)"]
B --> C["4 × factorial(3)"]
C --> D["3 × factorial(2)"]
D --> E["2 × factorial(1)"]
E --> F["retorna 1"]
F --> G["retorna 2 × 1 = 2"]
G --> H["retorna 3 × 2 = 6"]
H --> I["retorna 4 × 6 = 24"]
I --> J["retorna 5 × 24 = 120"]
Comparación: iterativo vs recursivo¶
El mismo problema puede resolverse de dos formas:
Ambas versiones producen el mismo resultado. La recursiva es más cercana a la definición matemática; la iterativa es más eficiente en memoria para números grandes.
El caso base es obligatorio
Sin caso base, la función se llama a sí misma indefinidamente hasta que Python detiene el programa con un RecursionError.
Suma recursiva de una lista¶
La recursividad no se limita a problemas matemáticos. Calcular la suma de una lista también puede expresarse recursivamente: la suma de una lista es el primer elemento más la suma del resto.
def suma_lista(lista):
if len(lista) == 0: # (1)!
return 0
return lista[0] + suma_lista(lista[1:]) # (2)!
- Caso base: una lista vacía tiene suma
0. - Caso recursivo: el primer elemento más la suma del resto de la lista.
15
¿Cuándo usar recursividad?
La recursividad es especialmente útil cuando el problema tiene una estructura naturalmente jerárquica o repetitiva que se reduce a sí misma. Para problemas simples de iteración, los ciclos suelen ser más claros y eficientes.
Ejercicio integrador¶
Una estudiante de décimo año necesita un programa para analizar las temperaturas registradas durante una semana. El programa debe organizarse completamente en funciones.
El programa debe cumplir con los siguientes requisitos:
- Definir una función
pedir_temperaturas()que solicite al usuario 7 temperaturas (una por día) y las retorne en una lista. Cada temperatura debe ser validada: debe estar entre-10y50grados Celsius. - Definir una función
calcular_estadisticas(temps)que reciba la lista y retorne una tupla con: promedio, temperatura mínima y temperatura máxima. - Definir una función
clasificar_dia(temp)que reciba una temperatura y retorne una clasificación:- Menor a 15°C:
"Frío" - Entre 15°C y 28°C:
"Agradable" - Mayor a 28°C:
"Caluroso"
- Menor a 15°C:
- Definir una función
mostrar_reporte(temps)que useclasificar_diapara imprimir la clasificación de cada día, luego muestre las estadísticas obtenidas decalcular_estadisticas. - El programa principal debe llamar a
pedir_temperaturas()y luego amostrar_reporte().
Paso 1: Función para validar y pedir temperaturas¶
Esta función usa un ciclo while para pedir cada temperatura y valida que esté dentro del rango permitido antes de agregarla a la lista.
def pedir_temperaturas():
dias = ["Lunes", "Martes", "Miércoles", "Jueves",
"Viernes", "Sábado", "Domingo"]
temperaturas = []
for dia in dias:
while True:
try:
temp = float(input(f"Temperatura del {dia} (°C): ")) # (1)!
if temp < -10 or temp > 50:
print("Error: la temperatura debe estar entre -10 y 50°C.")
else:
temperaturas.append(temp)
break
except ValueError:
print("Error: debe ingresar un número.")
return temperaturas
- Se usa
floatpara aceptar temperaturas con decimales como23.5.
Paso 2: Función para calcular estadísticas¶
Recibe la lista de temperaturas y retorna los tres valores calculados agrupados en una tupla.
def calcular_estadisticas(temps):
promedio = sum(temps) / len(temps)
minima = min(temps)
maxima = max(temps)
return promedio, minima, maxima # (1)!
- Python permite retornar múltiples valores separados por coma. El resultado es una tupla que puede desempaquetarse al recibirla.
Paso 3: Función para clasificar un día¶
Recibe una sola temperatura y retorna su categoría como string.
def clasificar_dia(temp):
if temp < 15:
return "Frío"
elif temp <= 28:
return "Agradable"
else:
return "Caluroso"
Paso 4: Función para mostrar el reporte¶
Esta función usa las otras funciones: llama a clasificar_dia para cada temperatura y a calcular_estadisticas para las estadísticas finales.
def mostrar_reporte(temps):
dias = ["Lunes", "Martes", "Miércoles", "Jueves",
"Viernes", "Sábado", "Domingo"]
print("\n--- Reporte semanal ---")
for i, temp in enumerate(temps): # (1)!
clasificacion = clasificar_dia(temp)
print(f"{dias[i]}: {temp:.1f}°C — {clasificacion}")
promedio, minima, maxima = calcular_estadisticas(temps) # (2)!
print(f"\nPromedio semanal: {promedio:.1f}°C")
print(f"Temperatura mínima: {minima:.1f}°C")
print(f"Temperatura máxima: {maxima:.1f}°C")
enumerateentrega el índice y el valor en cada iteración, lo que permite acceder al nombre del día correspondiente.- Los tres valores de la tupla se desempaquetan en tres variables separadas.
Programa completo¶
def pedir_temperaturas():
dias = ["Lunes", "Martes", "Miércoles", "Jueves",
"Viernes", "Sábado", "Domingo"]
temperaturas = []
for dia in dias:
while True:
try:
temp = float(input(f"Temperatura del {dia} (°C): "))
if temp < -10 or temp > 50:
print("Error: la temperatura debe estar entre -10 y 50°C.")
else:
temperaturas.append(temp)
break
except ValueError:
print("Error: debe ingresar un número.")
return temperaturas
def calcular_estadisticas(temps):
promedio = sum(temps) / len(temps)
minima = min(temps)
maxima = max(temps)
return promedio, minima, maxima
def clasificar_dia(temp):
if temp < 15:
return "Frío"
elif temp <= 28:
return "Agradable"
else:
return "Caluroso"
def mostrar_reporte(temps):
dias = ["Lunes", "Martes", "Miércoles", "Jueves",
"Viernes", "Sábado", "Domingo"]
print("\n--- Reporte semanal ---")
for i, temp in enumerate(temps):
clasificacion = clasificar_dia(temp)
print(f"{dias[i]}: {temp:.1f}°C — {clasificacion}")
promedio, minima, maxima = calcular_estadisticas(temps)
print(f"\nPromedio semanal: {promedio:.1f}°C")
print(f"Temperatura mínima: {minima:.1f}°C")
print(f"Temperatura máxima: {maxima:.1f}°C")
# Programa principal
temperaturas = pedir_temperaturas()
mostrar_reporte(temperaturas)
Ejemplos de ejecución
Temperatura del Lunes (°C): 22
Temperatura del Martes (°C): 18
Temperatura del Miércoles (°C): 30
Temperatura del Jueves (°C): 27
Temperatura del Viernes (°C): 14
Temperatura del Sábado (°C): 12
Temperatura del Domingo (°C): 25
--- Reporte semanal ---
Lunes: 22.0°C — Agradable
Martes: 18.0°C — Agradable
Miércoles: 30.0°C — Caluroso
Jueves: 27.0°C — Agradable
Viernes: 14.0°C — Frío
Sábado: 12.0°C — Frío
Domingo: 25.0°C — Agradable
Promedio semanal: 21.1°C
Temperatura mínima: 12.0°C
Temperatura máxima: 30.0°C
Ejercicios adicionales¶
Como funciones es un tema tan amplio, a continuación se muestran 10 ejercicios resueltos para practicar los conceptos vistos hasta el momento.
1. Clasificar triángulo¶
Escriba dos funciones: es_valido(a, b, c) que verifique si tres lados forman un triángulo (la suma de cualquier par de lados debe ser mayor que el tercero), y clasificar_triangulo(a, b, c) que retorne "Equilátero", "Isósceles", "Escaleno" o "Inválido" según corresponda. El programa debe pedir los tres lados al usuario.
def es_valido(a, b, c):
return a + b > c and a + c > b and b + c > a
def clasificar_triangulo(a, b, c):
if not es_valido(a, b, c):
return "Inválido"
if a == b == c:
return "Equilátero"
if a == b or b == c or a == c:
return "Isósceles"
return "Escaleno"
a = float(input("Lado a: "))
b = float(input("Lado b: "))
c = float(input("Lado c: "))
print(clasificar_triangulo(a, b, c))
Observe el uso de una función que retorna un booleano como condición dentro de un
if. Esta es una práctica común.
2. Fibonacci recursivo¶
Escriba una función recursiva fibonacci(n) que retorne el n-ésimo número de la secuencia de Fibonacci, donde fibonacci(0) = 0 y fibonacci(1) = 1. El programa debe pedir un número al usuario e imprimir el resultado.
La secuencia comienza: 0, 1, 1, 2, 3, 5, 8, 13, 21, …
def fibonacci(n):
if n == 0: # (1)!
return 0
if n == 1: # (2)!
return 1
return fibonacci(n - 1) + fibonacci(n - 2) # (3)!
n = int(input("Posición en la secuencia: "))
print(f"Fibonacci({n}) = {fibonacci(n)}")
- Caso base: el término 0 es 0.
- Caso base: el término 1 es 1.
- Caso recursivo: cada término es la suma de los dos anteriores.
3. Contar vocales¶
Escriba una función contar_vocales(texto) que reciba una cadena de texto y retorne la cantidad de vocales que contiene (sin distinguir mayúsculas de minúsculas). El programa debe pedir una oración al usuario e imprimir el resultado.
def contar_vocales(texto):
vocales = "aeiouáéíóúAEIOUÁÉÍÓÚ"
contador = 0
for caracter in texto: # (1)!
if caracter in vocales:
contador += 1
return contador
oracion = input("Ingrese una oración: ")
print(f"Cantidad de vocales: {contar_vocales(oracion)}")
- Se recorre la cadena carácter por carácter y se verifica si pertenece al string de vocales.
4. Estadísticas de una lista¶
Escriba una función estadisticas(lista) que reciba una lista de números y retorne una tupla con tres valores: el promedio, el mínimo y el máximo. El programa debe pedir al usuario 5 números, llamar a la función e imprimir los tres resultados.
def estadisticas(lista):
promedio = sum(lista) / len(lista)
return promedio, min(lista), max(lista) # (1)!
numeros = []
for i in range(5):
numeros.append(float(input(f"Número {i + 1}: ")))
promedio, minimo, maximo = estadisticas(numeros) # (2)!
print(f"Promedio: {promedio:.2f}")
print(f"Mínimo: {minimo}")
print(f"Máximo: {maximo}")
- Se retornan tres valores separados por coma; Python los empaqueta automáticamente en una tupla.
- Los tres valores se desempaquetan en tres variables al recibirlos.
5. Validar contraseña¶
Escriba una función validar_contrasena(clave) que verifique si una contraseña cumple todas las siguientes reglas y retorne una lista de errores (vacía si es válida):
- Tiene al menos 8 caracteres.
- Contiene al menos una letra mayúscula.
- Contiene al menos un dígito.
El programa debe pedir la contraseña e informar si es válida o cuáles reglas no se cumplen.
def validar_contrasena(clave):
errores = []
if len(clave) < 8:
errores.append("Debe tener al menos 8 caracteres.")
if not any(c.isupper() for c in clave): # (1)!
errores.append("Debe contener al menos una mayúscula.")
if not any(c.isdigit() for c in clave): # (2)!
errores.append("Debe contener al menos un dígito.")
return errores
clave = input("Ingrese una contraseña: ")
errores = validar_contrasena(clave)
if not errores:
print("Contraseña válida.")
else:
for error in errores:
print(f"- {error}")
anyretornaTruesi al menos un carácter cumple la condición;isupper()verifica si es mayúscula.isdigit()verifica si el carácter es un dígito del 0 al 9.
6. Tabla de multiplicar¶
Escriba una función tabla_multiplicar(n, limite=10) que imprima la tabla de multiplicar del número n desde 1 hasta limite. El parámetro limite debe tener valor por defecto de 10. El programa debe pedir el número al usuario y, opcionalmente, hasta qué múltiplo mostrar.
def tabla_multiplicar(n, limite=10):
for i in range(1, limite + 1):
print(f"{n} × {i} = {n * i}")
n = int(input("Número: "))
respuesta = input("¿Hasta qué múltiplo? (Enter para usar 10): ")
if respuesta == "": # (1)!
tabla_multiplicar(n)
else:
tabla_multiplicar(n, int(respuesta))
- Si el usuario no ingresa nada, se usa el valor por defecto del parámetro
limite.
7. Potencia recursiva¶
Escriba una función recursiva potencia(base, exp) que calcule base elevado a exp sin usar el operador **. El exponente siempre será un entero no negativo. El programa debe pedir ambos valores al usuario.
Pista: base^0 = 1 y base^n = base × base^(n-1).
def potencia(base, exp):
if exp == 0: # (1)!
return 1
return base * potencia(base, exp - 1) # (2)!
base = float(input("Base: "))
exp = int(input("Exponente (entero ≥ 0): "))
print(f"{base} ^ {exp} = {potencia(base, exp)}")
- Caso base: cualquier número elevado a 0 es 1.
- Caso recursivo:
base^nesbasemultiplicado porbase^(n-1).
8. Verificar palíndromo¶
Escriba una función es_palindromo(palabra) que retorne True si la palabra es un palíndromo (se lee igual de izquierda a derecha que de derecha a izquierda) y False en caso contrario. La función debe ignorar mayúsculas y minúsculas. El programa debe pedir una palabra al usuario e informar el resultado.
def es_palindromo(palabra):
palabra = palabra.lower() # (1)!
return palabra == palabra[::-1] # (2)!
palabra = input("Ingrese una palabra: ")
if es_palindromo(palabra):
print(f'"{palabra}" es un palíndromo.')
else:
print(f'"{palabra}" no es un palíndromo.')
- Se convierte a minúsculas para que la comparación no distinga entre
Aya. [::-1]invierte la cadena; si es igual a sí misma invertida, es un palíndromo.
9. Análisis de calificaciones¶
Escriba un programa con tres funciones para analizar las notas de un grupo de estudiantes:
pedir_notas(cantidad)— solicitacantidadnotas al usuario (entre 0 y 100) y las retorna en una lista.clasificar(nota)— retorna"Aprobado"si la nota es mayor o igual a 70, o"Reprobado"en caso contrario.mostrar_reporte(notas)— imprime cada nota con su clasificación, el promedio del grupo y cuántos aprobaron.
def pedir_notas(cantidad):
notas = []
for i in range(cantidad):
continuar = True
while continuar:
try:
nota = float(input(f"Nota {i + 1}: "))
if 0 <= nota <= 100:
notas.append(nota)
continuar = False
else:
print("La nota debe estar entre 0 y 100.")
except ValueError:
print("Ingrese un número válido.")
return notas
def clasificar(nota):
return "Aprobado" if nota >= 70 else "Reprobado"
def mostrar_reporte(notas):
print("\n--- Reporte del grupo ---")
aprobados = 0
for i, nota in enumerate(notas):
estado = clasificar(nota) # (1)!
if estado == "Aprobado":
aprobados += 1
print(f"Estudiante {i + 1}: {nota:.1f} — {estado}")
print(f"\nPromedio: {sum(notas) / len(notas):.1f}")
print(f"Aprobados: {aprobados} de {len(notas)}")
cantidad = int(input("¿Cuántos estudiantes? "))
notas = pedir_notas(cantidad)
mostrar_reporte(notas)
mostrar_reportedelega la clasificación de cada nota aclasificar, que tiene una sola responsabilidad.
10. Suma de dígitos¶
Escriba una función recursiva suma_digitos(n) que reciba un número entero positivo y retorne la suma de todos sus dígitos. El programa debe pedir un número al usuario e imprimir el resultado.
Por ejemplo: suma_digitos(1234) → 1 + 2 + 3 + 4 = 10.
def suma_digitos(n):
if n < 10: # (1)!
return n
return n % 10 + suma_digitos(n // 10) # (2)!
n = int(input("Ingrese un número entero positivo: "))
print(f"Suma de dígitos de {n}: {suma_digitos(n)}")
- Caso base: un número de un solo dígito es él mismo.
- Caso recursivo: el último dígito (
n % 10) más la suma de los dígitos restantes (n // 10elimina el último dígito).