funciones en Python ejercicios resueltos chuletario

Funciones en Python — ejercicios para afianzar lo que sabes

Las funciones en Python ejercicios con solución son el cierre perfecto de este tema. Ya viste la teoría y practicaste con programas reales. Ahora toca resolver por tu cuenta. Cuatro ejercicios en tres niveles con especial atención al error más silencioso de todos: olvidar el return y trabajar sin darte cuenta con None.

Como siempre: intenta resolverlo, usa la pista si llevas más de 10 minutos atascado, compara con la solución comentada al final y usa pythontutor.com


Funciones en Python ejercicios — Nivel Básico

Ejercicio 1 — Conversor de notas entre sistemas

Escribe un conjunto de funciones que conviertan notas entre tres sistemas diferentes: el sistema español (0-10), el sistema americano (0-100) y el sistema de letras americano (A, B, C, D, F).

Las conversiones son:

  • Española → Americana: multiplica por 10
  • Americana → Española: divide entre 10
  • Española → Letra: 9-10=A, 7-8=B, 5-6=C, 3-4=D, 0-2=F
  • Letra → Española: A=9.5, B=7.5, C=5.5, D=3.5, F=1.5

La salida debe ser:

=== CONVERSOR DE NOTAS ===
Nota española (0-10): 7.5

--- Conversiones ---
Sistema español:    7.5
Sistema americano:  75.0
Sistema de letras:  B

💡 Pista — el error del return: Cada función debe devolver el valor con return, no imprimirlo con print. Si usas print dentro de la función y luego intentas hacer nota_americana = española_a_americana(7.5), la variable valdrá None aunque veas el número en pantalla. La función imprime pero no devuelve nada. Siempre return.


Ejercicio 2 — Generador de informe de notas

Usando las funciones del ejercicio anterior, escribe un programa que pida las notas de 4 asignaturas y genere un informe completo con la media, la nota más alta, la más baja y la conversión de cada nota a los tres sistemas.

=== INFORME DE NOTAS ===

Asignatura 1: FP1
Nota (0-10): 8.5
Asignatura 2: Estadística
Nota (0-10): 7.0
Asignatura 3: Matemáticas
Nota (0-10): 6.5
Asignatura 4: Bases de datos
Nota (0-10): 9.0

--- Informe completo ---
FP1:           8.5 | 85.0 | A
Estadística:   7.0 | 70.0 | B
Matemáticas:   6.5 | 65.0 | C
Bases de datos: 9.0 | 90.0 | A

Media:         7.75 → B
Más alta:      9.0 (Bases de datos)
Más baja:      6.5 (Matemáticas)

💡 Pista: Reutiliza las funciones del ejercicio anterior, eso es exactamente para lo que sirven. Crea una función pedir_asignatura() que pida nombre y nota y devuelva ambos. Crea otra función generar_informe(asignaturas) que reciba la lista y genere el resumen. El error del return aquí aparece si pedir_asignatura() hace print en vez de return, luego no puedes guardar los datos.


Funciones en Python ejercicios — Nivel Intermedio

Ejercicio 3 — Mini banco con funciones

Simula un sistema bancario básico con funciones para cada operación. El banco debe permitir consultar saldo, depositar dinero, retirar dinero y ver el historial de movimientos.

=== BANCO SERGIO LEARNS ===

Saldo inicial: 1000.0 €

1. Consultar saldo
2. Depositar
3. Retirar
4. Ver historial
0. Salir

Opción: 2
Cantidad a depositar: 500

✓ Depósito realizado: +500.0 €
Saldo actual: 1500.0 €

Opción: 3
Cantidad a retirar: 200

✓ Retirada realizada: -200.0 €
Saldo actual: 1300.0 €

Opción: 4

--- Historial de movimientos ---
Saldo inicial:    +1000.0 €
Depósito:         +500.0 €
Retirada:         -200.0 €
─────────────────────────────
Saldo actual:     1300.0 €

💡 Pistas:

  • Crea estas funciones: consultar_saldo(saldo), depositar(saldo, cantidad), retirar(saldo, cantidad), mostrar_historial(historial), menu_banco()
  • Las funciones depositar y retirar deben devolver el nuevo saldo, ese es el return clave. Si olvidas el return el saldo nunca se actualiza aunque la función parezca funcionar
  • Guarda el historial como una lista de strings que vas actualizando con cada operación
  • retirar debe comprobar que hay saldo suficiente antes de retirar

Funciones en Python ejercicios — Desafío Final

Ejercicio 4 — Juego de dados con estadísticas

Simula un juego de dados donde el jugador lanza dos dados un número determinado de veces. El programa debe mostrar cada lanzamiento y al final generar estadísticas completas.

=== JUEGO DE DADOS ===
¿Cuántos lanzamientos? 5

Lanzamiento 1: 🎲 3 + 🎲 5 = 8
Lanzamiento 2: 🎲 6 + 🎲 6 = 12 ← ¡Doble!
Lanzamiento 3: 🎲 2 + 🎲 4 = 6
Lanzamiento 4: 🎲 1 + 🎲 1 = 2 ← ¡Doble!
Lanzamiento 5: 🎲 4 + 🎲 3 = 7

--- Estadísticas ---
Total lanzamientos: 5
Suma total:         35
Media por lanzamiento: 7.0
Máximo obtenido:    12 (lanzamiento 2)
Mínimo obtenido:    2 (lanzamiento 4)
Dobles conseguidos: 2 (40.0%)
Distribución de resultados:
  2: ██ (1 vez)
  6: ██ (1 vez)
  7: ██ (1 vez)
  8: ██ (1 vez)
  12: ██ (1 vez)

💡 Pistas:

  • Crea estas funciones: lanzar_dado(), lanzar_dos_dados(), es_doble(dado1, dado2), calcular_estadisticas(resultados), mostrar_distribucion(resultados), jugar()
  • lanzar_dado() debe devolver el valor — si usa print en vez de return no podrás sumar los dados
  • lanzar_dos_dados() debe devolver una tupla (dado1, dado2) — así puedes desempaquetar con d1, d2 = lanzar_dos_dados()
  • Para la distribución usa un diccionario donde la clave es el resultado y el valor es cuántas veces apareció
  • Los bloques de la distribución se hacen con "█" * cantidad

Soluciones Comentadas

Solución Ejercicio 1:

# Conversor de notas entre sistemas
def española_a_americana(nota):
    return round(nota * 10, 1)

def americana_a_española(nota):
    return round(nota / 10, 1)

def española_a_letra(nota):
    if nota >= 9:
        return "A"
    elif nota >= 7:
        return "B"
    elif nota >= 5:
        return "C"
    elif nota >= 3:
        return "D"
    else:
        return "F"

def letra_a_española(letra):
    equivalencias = {"A": 9.5, "B": 7.5, "C": 5.5, "D": 3.5, "F": 1.5}
    return equivalencias.get(letra.upper(), None)

def mostrar_conversiones(nota_española):
    americana = española_a_americana(nota_española)
    letra = española_a_letra(nota_española)
    print(f"\n--- Conversiones ---")
    print(f"Sistema español:    {nota_española}")
    print(f"Sistema americano:  {americana}")
    print(f"Sistema de letras:  {letra}")

print("=== CONVERSOR DE NOTAS ===")
nota = float(input("Nota española (0-10): "))

if nota < 0 or nota > 10:
    print("Error: la nota debe estar entre 0 y 10")
else:
    mostrar_conversiones(nota)

Solución Ejercicio 2:

# Informe de notas — reutiliza funciones del ejercicio 1
def pedir_asignatura(numero):
    nombre = input(f"Asignatura {numero}: ")
    nota = float(input(f"Nota (0-10): "))
    while nota < 0 or nota > 10:
        print("Error: entre 0 y 10")
        nota = float(input(f"Nota (0-10): "))
    return nombre, nota

def generar_informe(asignaturas):
    print("\n--- Informe completo ---")
    notas = []

    for nombre, nota in asignaturas:
        americana = española_a_americana(nota)
        letra = española_a_letra(nota)
        print(f"{nombre:<20} {nota} | {americana} | {letra}")
        notas.append(nota)

    media = round(sum(notas) / len(notas), 2)
    nota_max = max(notas)
    nota_min = min(notas)
    nombre_max = asignaturas[notas.index(nota_max)][0]
    nombre_min = asignaturas[notas.index(nota_min)][0]

    print(f"\nMedia:         {media} → {española_a_letra(media)}")
    print(f"Más alta:      {nota_max} ({nombre_max})")
    print(f"Más baja:      {nota_min} ({nombre_min})")

print("=== INFORME DE NOTAS ===\n")
asignaturas = []
for i in range(1, 5):
    nombre, nota = pedir_asignatura(i)
    asignaturas.append((nombre, nota))
    print()

generar_informe(asignaturas)

Solución Ejercicio 3:

# Mini banco con funciones
def consultar_saldo(saldo):
    print(f"\nSaldo actual: {saldo} €")

def depositar(saldo, cantidad):
    if cantidad <= 0:
        print("Error: la cantidad debe ser positiva")
        return saldo    # devuelve el saldo sin cambios
    nuevo_saldo = round(saldo + cantidad, 2)
    print(f"✓ Depósito realizado: +{cantidad} €")
    print(f"Saldo actual: {nuevo_saldo} €")
    return nuevo_saldo    # RETURN clave — devuelve el nuevo saldo

def retirar(saldo, cantidad):
    if cantidad <= 0:
        print("Error: la cantidad debe ser positiva")
        return saldo
    if cantidad > saldo:
        print(f"Error: saldo insuficiente. Tienes {saldo} €")
        return saldo
    nuevo_saldo = round(saldo - cantidad, 2)
    print(f"✓ Retirada realizada: -{cantidad} €")
    print(f"Saldo actual: {nuevo_saldo} €")
    return nuevo_saldo

def mostrar_historial(historial, saldo):
    print("\n--- Historial de movimientos ---")
    for movimiento in historial:
        print(movimiento)
    print("─" * 33)
    print(f"Saldo actual:     {saldo} €")

def menu_banco():
    print("=== BANCO SERGIO LEARNS ===\n")
    saldo_inicial = float(input("Saldo inicial: "))
    saldo = saldo_inicial
    historial = [f"Saldo inicial:    +{saldo_inicial} €"]

    while True:
        print("\n1. Consultar saldo")
        print("2. Depositar")
        print("3. Retirar")
        print("4. Ver historial")
        print("0. Salir")

        opcion = input("\nOpción: ")

        if opcion == "0":
            print("Hasta pronto")
            break
        elif opcion == "1":
            consultar_saldo(saldo)
        elif opcion == "2":
            cantidad = float(input("Cantidad a depositar: "))
            saldo_anterior = saldo
            saldo = depositar(saldo, cantidad)
            if saldo != saldo_anterior:
                historial.append(f"Depósito:         +{cantidad} €")
        elif opcion == "3":
            cantidad = float(input("Cantidad a retirar: "))
            saldo_anterior = saldo
            saldo = retirar(saldo, cantidad)
            if saldo != saldo_anterior:
                historial.append(f"Retirada:         -{cantidad} €")
        elif opcion == "4":
            mostrar_historial(historial, saldo)
        else:
            print("Opción no válida")

menu_banco()

Solución Ejercicio 4:

# Juego de dados con estadísticas
import random

def lanzar_dado():
    return random.randint(1, 6)    # RETURN — devuelve el valor

def lanzar_dos_dados():
    return lanzar_dado(), lanzar_dado()    # devuelve tupla

def es_doble(dado1, dado2):
    return dado1 == dado2

def calcular_estadisticas(resultados):
    sumas = [d1 + d2 for d1, d2 in resultados]
    dobles = sum(1 for d1, d2 in resultados if es_doble(d1, d2))
    return {
        "total": len(resultados),
        "suma_total": sum(sumas),
        "media": round(sum(sumas) / len(sumas), 2),
        "maximo": max(sumas),
        "lanz_max": sumas.index(max(sumas)) + 1,
        "minimo": min(sumas),
        "lanz_min": sumas.index(min(sumas)) + 1,
        "dobles": dobles,
        "pct_dobles": round(dobles / len(resultados) * 100, 1),
        "sumas": sumas
    }

def mostrar_distribucion(sumas):
    print("Distribución de resultados:")
    conteo = {}
    for s in sumas:
        conteo[s] = conteo.get(s, 0) + 1
    for valor in sorted(conteo.keys()):
        barra = "█" * conteo[valor]
        print(f"  {valor:2d}: {barra} ({conteo[valor]} vez)")

def jugar():
    print("=== JUEGO DE DADOS ===")
    n = int(input("¿Cuántos lanzamientos? "))
    resultados = []

    print()
    for i in range(1, n + 1):
        d1, d2 = lanzar_dos_dados()
        suma = d1 + d2
        doble = " ← ¡Doble!" if es_doble(d1, d2) else ""
        print(f"Lanzamiento {i}: 🎲 {d1} + 🎲 {d2} = {suma}{doble}")
        resultados.append((d1, d2))

    stats = calcular_estadisticas(resultados)
    print(f"\n--- Estadísticas ---")
    print(f"Total lanzamientos: {stats['total']}")
    print(f"Suma total:         {stats['suma_total']}")
    print(f"Media por lanzamiento: {stats['media']}")
    print(f"Máximo obtenido:    {stats['maximo']} (lanzamiento {stats['lanz_max']})")
    print(f"Mínimo obtenido:    {stats['minimo']} (lanzamiento {stats['lanz_min']})")
    print(f"Dobles conseguidos: {stats['dobles']} ({stats['pct_dobles']}%)")
    mostrar_distribucion(stats['sumas'])

jugar()

💡 Nota: aquí usamos listas y diccionarios que veremos en profundidad en el próximos tema. Por ahora trátalo como una colección de valores.


Chuletario — Funciones en Python

# ============================================
# CHULETARIO — Funciones en Python
# Sergio Learns · sergiolearns.com
# ============================================

# DEFINIR UNA FUNCIÓN
def nombre_funcion(parametro1, parametro2):
    # cuerpo
    return resultado

# LLAMAR A UNA FUNCIÓN
resultado = nombre_funcion(argumento1, argumento2)

# PARÁMETRO vs ARGUMENTO
def saludar(nombre):     # nombre = PARÁMETRO (en la definición)
    return f"Hola, {nombre}"

saludar("Sergio")        # "Sergio" = ARGUMENTO (en la llamada)

# PARÁMETROS CON VALOR POR DEFECTO
def saludar(nombre, saludo="Hola"):
    return f"{saludo}, {nombre}"

saludar("Sergio")              # → "Hola, Sergio"
saludar("Sergio", "Buenos días")  # → "Buenos días, Sergio"

# RETURN — devuelve valor Y termina la función
def sumar(a, b):
    return a + b      # termina aquí
    print("nunca")    # código muerto — nunca se ejecuta

# SIN RETURN → devuelve None
def imprimir(x):
    print(x)          # imprime pero NO devuelve

resultado = imprimir(5)
print(resultado)      # → None ← error silencioso típico

# REGLA: si necesitas usar el resultado → usa return
#        si solo necesitas que haga algo → no hace falta

# DEVOLVER MÚLTIPLES VALORES (tupla)
def min_max(lista):
    return min(lista), max(lista)

minimo, maximo = min_max([3, 1, 4, 1, 5])

# FUNCIONES QUE LLAMAN A OTRAS
def es_aprobado(nota):
    return nota >= 5

def clasificar(nota):
    if nota >= 9: return "Sobresaliente"
    elif nota >= 7: return "Notable"
    elif es_aprobado(nota): return "Aprobado"  # llama a otra función
    else: return "Suspenso"

# ALCANCE — local vs global
x = 10              # global

def mi_funcion():
    y = 20          # local — solo existe aquí
    print(x)        # puede leer globales
    print(y)

mi_funcion()
print(x)    # → 10 ✓
print(y)    # → NameError ✗ — y no existe fuera

# CONSTANTES GLOBALES — en mayúsculas
IVA = 0.21
MAX_INTENTOS = 3

# PATRÓN: separar cálculo de presentación
def calcular(datos):      # solo calcula, usa return
    return resultado

def mostrar(resultado):   # solo muestra, usa print
    print(resultado)

def main():               # coordina todo
    datos = input("...")
    resultado = calcular(datos)
    mostrar(resultado)

# ERRORES TÍPICOS
# 1. Olvidar return → función devuelve None
# 2. print en vez de return → valor no se puede usar
# 3. Llamar función antes de definirla → NameError
# 4. Variable local usada fuera → NameError
# 5. Modificar global desde función → bug difícil de encontrar

# DRY: Don't Repeat Yourself
# Si copias y pegas código → conviértelo en función

Publicaciones Similares

Un comentario

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *