Saltar al contenido principal

Bloque 108. Depuración de programas

Contenidos

Revisa los siguientes apartados de la Unidad para resolver los ejercicios:

En este bloque no escribes programas nuevos: depuras código que ya existe pero falla, usando trazas con print() y el depurador del IDE (puntos de interrupción, inspección de variables, ejecución paso a paso).

Ejercicio 1. Encuentra el error de lógica

El siguiente script calcula la media de tres notas, pero devuelve un resultado incorrecto. Copia el código exactamente como está en un fichero media.py:

def calcular_media(nota1, nota2, nota3):
total = nota1 + nota2 + nota3
media = total / 2
return media

n1 = float(input("Nota 1: "))
n2 = float(input("Nota 2: "))
n3 = float(input("Nota 3: "))

print("La media es:", calcular_media(n1, n2, n3))

Sin reescribirlo de cero:

  1. Añade trazas con print() en los puntos clave para ver los valores intermedios.
  2. Identifica la línea exacta donde el resultado deja de ser el esperado.
  3. Corrige el error y elimina las trazas de depuración que ya no necesites.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 2. Depuración con breakpoints

Copia el código exactamente como está en un fichero digitos.py: es un juego donde hay que adivinar, uno a uno, los 4 dígitos de un número secreto fijo, con 6 intentos en total.

def comprobar_digito(numero_secreto, posicion, digito_propuesto):
divisor = 10 ** (3 - posicion)
digito_real = (numero_secreto // divisor) % 10
return digito_real == digito_propuesto

numero_secreto = 4271
intentos_restantes = 6
digitos_acertados = 0

while intentos_restantes > 0 and digitos_acertados < 4:
posicion = digitos_acertados
digito_propuesto = int(input("Dígito " + str(posicion + 1) + ": ¿cuál es? "))

if comprobar_digito(numero_secreto, posicion, digito_propuesto):
digitos_acertados += 1
print("¡Correcto! Llevas", digitos_acertados, "dígitos acertados.")
else:
intentos_restantes -= 1
print("Incorrecto. Te quedan", intentos_restantes, "intentos.")

if digitos_acertados == 4:
print("¡Has ganado!")
else:
print("Has perdido. El número secreto era", numero_secreto)

Usando el depurador del IDE (no print() esta vez):

  1. Coloca un punto de interrupción justo antes de la línea if comprobar_digito(...).
  2. Ejecuta el programa paso a paso durante 2-3 iteraciones del bucle, observando cómo cambian las variables (intentos_restantes, digitos_acertados...) en el panel de variables del depurador. Prueba tanto step over (ejecutar una línea sin entrar en las funciones que llama) como step into (entrar dentro de una función para ver su ejecución por dentro) al menos una vez cada uno, y anota qué diferencia observas entre ambos.
  3. Escribe en un docstring un breve resumen (3-4 líneas) de qué ves en el depurador que no verías solo leyendo el código.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 3. Rompe tu propio programa

Copia el código exactamente como está en un fichero adivina.py: es el clásico "adivina el número", que genera un número secreto aleatorio entre 1 y 100 y da pistas ("más alto"/"más bajo") en cada intento.

import random

def generar_numero_secreto():
return random.randint(1, 100)

def comprobar_intento(numero_secreto, intento):
if intento < numero_secreto:
return "mas_bajo"
elif intento > numero_secreto:
return "mas_alto"
else:
return "acierto"

numero_secreto = generar_numero_secreto()
intentos = 0
resultado = ""

while resultado != "acierto":
intento = int(input("Propón un número entre 1 y 100: "))
intentos += 1
resultado = comprobar_intento(numero_secreto, intento)

if resultado == "mas_bajo":
print("El número secreto es más alto")
elif resultado == "mas_alto":
print("El número secreto es más bajo")

print("¡Acertaste! Has necesitado", intentos, "intentos.")

Introduce a propósito un error de tipo off-by-one (por ejemplo, cambia la comparación intento < numero_secreto por intento <= numero_secreto). Sin deshacer el cambio, usa trazas con print() para localizar en qué situación concreta el programa se comporta mal, confirma que es el cambio que introdujiste y corrígelo. El objetivo es practicar cómo se acorrala un error a partir de sus síntomas, no solo corregir errores ajenos.

Off-by-one

Un "error por uno" (o off-by-one error) es un fallo de lógica en el que un cálculo o conteo se pasa por exactamente una unidad, ya sea de más o de menos. Ocurre a menudo cuando un bucle iterativo se repite una vez más o una vez menos que lo necesario.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 4. Programa con varios errores

El siguiente script tiene tres errores distintos introducidos a propósito: uno de sintaxis, uno de tipos y uno de lógica. Copia el código exactamente como está en un fichero caja.py:

def anadir_producto(total, contador, nombre, precio):
nuevo_total = total + precio
nuevo_contador = contador + 1
print("Añadido:", nombre, "(", precio, "€). Total:", nuevo_total, "€, artículos:", nuevo_contador)
return nuevo_total, nuevo_contador


def cerrar_ticket(total, contador)
print("Ticket cerrado. Total:", total, "€, artículos:", contador)
return 0, 0


total = 0
contador = 0

while True:
opcion = input("a) Añadir producto c) Cerrar ticket s) Salir: ")

if opcion == "a":
nombre = input("Nombre del producto: ")
precio = input("Precio: ")
total, contador = anadir_producto(total, contador, nombre, precio)
elif opcion == "c":
total, contador = cerrar_ticket(total, contador)
elif opcion == "s":
break
else:
print("Opción no válida")

print("Total acumulado final:", contador)

Encuéntralos y corrígelos uno a uno, anotando en un comentario, junto a cada corrección, qué tipo de error era.

Ten en cuenta que:

  • El de sintaxis impide ejecutar el script.
  • El de tipos se manifiesta en cuanto añades el primer producto.
  • El de lógica no da ningún error, pero el dato final mostrado no es el correcto.

💾 Haz un commit al terminar el ejercicio.

Repaso

Al terminar los ejercicios, debes tener claro los siguientes conceptos:

  • Trazas de depuración con print()
  • Puntos de interrupción (breakpoints)
  • Ejecución paso a paso (step over / step into)
  • Inspección de variables en el depurador
  • Tipos de error: de sintaxis, de tipos y de lógica
  • Comentar el código para facilitar su revisión