Objetivo del mini-reto
Vas a construir una calculadora por consola con un menú de opciones (sumar, restar, multiplicar, dividir) y manejo de errores para entradas inválidas. El foco del reto no es “hacer cuentas”, sino crear una experiencia robusta: que el programa no se rompa si el usuario escribe texto, deja vacío, elige una opción inexistente o intenta dividir entre cero.
Qué significa “manejo de errores” aquí
En una app de consola, los errores más comunes vienen de dos fuentes: (1) el usuario escribe algo que no se puede convertir al tipo que necesitas (por ejemplo, letras cuando esperas un número), y (2) ocurre un caso inválido durante la operación (por ejemplo, división entre cero). En Python, esto se gestiona con excepciones usando try/except. La idea es: intentas ejecutar una acción “riesgosa” y, si falla, capturas el error y muestras un mensaje claro, sin cerrar el programa.
Errores típicos que vamos a cubrir
- ValueError: cuando
float("abc")falla porque no es un número. - ZeroDivisionError: cuando intentas dividir por 0.
- Opción inválida: cuando el usuario elige algo fuera del menú (esto no es excepción automática; lo validas tú).
Diseño del programa (antes de escribir código)
Para que el reto sea fácil de mantener, usa esta estructura mental:
- Entrada: leer opción del menú y dos números.
- Validación: asegurar que la opción existe y que los números son válidos.
- Proceso: ejecutar la operación elegida.
- Salida: mostrar el resultado o un mensaje de error.
- Bucle principal: repetir hasta que el usuario elija salir.
Guía práctica paso a paso
Paso 1: Define el menú y las opciones
El menú debe ser claro y repetirse en cada ciclo. Incluye una opción para salir.
def mostrar_menu():
print("\n=== Calculadora ===")
print("1) Sumar")
print("2) Restar")
print("3) Multiplicar")
print("4) Dividir")
print("0) Salir")Paso 2: Crea una función para leer números con seguridad
En vez de repetir try/except cada vez que pidas un número, encapsúlalo en una función. Esta función seguirá preguntando hasta recibir un número válido.
Continúa en nuestra aplicación.
Podrás escuchar el audiolibro con la pantalla apagada, recibir un certificado gratuito para este curso y además tener acceso a otros 5.000 cursos online gratuitos.
O continúa leyendo más abajo...Descargar la aplicación
def leer_numero(mensaje):
while True:
texto = input(mensaje)
try:
return float(texto)
except ValueError:
print("Entrada inválida. Escribe un número (ej: 3, 2.5, -10).")Paso 3: Implementa las operaciones con control de casos inválidos
Puedes resolverlo con una función que reciba la opción y los números. Para la división, protege el caso de divisor cero. Aquí tienes una versión que lanza errores controlados con mensajes claros.
def calcular(opcion, a, b):
if opcion == "1":
return a + b
elif opcion == "2":
return a - b
elif opcion == "3":
return a * b
elif opcion == "4":
if b == 0:
raise ZeroDivisionError("No se puede dividir entre cero")
return a / b
else:
raise ValueError("Opción no válida")Nota: aquí usamos raise para unificar el manejo de errores en un solo lugar (el bucle principal). También podrías devolver None y manejarlo, pero las excepciones te obligan a tratar el problema explícitamente.
Paso 4: Construye el bucle principal con manejo de errores
Este es el “centro de control”: muestra menú, lee opción, decide si salir, pide números y ejecuta. El objetivo es que cualquier fallo se traduzca en un mensaje y el programa continúe.
def main():
while True:
mostrar_menu()
opcion = input("Elige una opción: ").strip()
if opcion == "0":
break
if opcion not in {"1", "2", "3", "4"}:
print("Opción inválida. Elige 1, 2, 3, 4 o 0.")
continue
a = leer_numero("Primer número: ")
b = leer_numero("Segundo número: ")
try:
resultado = calcular(opcion, a, b)
print(f"Resultado: {resultado}")
except ZeroDivisionError:
print("Error: no se puede dividir entre cero.")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()Pruebas rápidas (casos que debes intentar)
Antes de dar el reto por terminado, prueba manualmente estos escenarios para confirmar que tu manejo de errores funciona:
- Elegir una opción inválida:
9,x, vacío. - Escribir texto cuando pide números:
hola,3,5(coma), espacios. - Dividir entre cero: opción 4, segundo número 0.
- Números negativos y decimales:
-2,0.25.
Mejoras opcionales (sub-retos)
1) Formato del resultado
Muestra el resultado con 2 decimales solo si es decimal, o siempre con 2 decimales.
print(f"Resultado: {resultado:.2f}")2) Confirmación antes de salir
Pide confirmación para evitar salidas accidentales.
if opcion == "0":
confirmar = input("¿Seguro que quieres salir? (s/n): ").strip().lower()
if confirmar == "s":
break
continue3) Historial de operaciones (sin listas)
Guarda solo la última operación en una variable de texto y muéstrala en el menú como “último cálculo”.
ultima = "(sin cálculos aún)"
# ...
print(f"Último: {ultima}")
# ...
ultima = f"{a} / {b} = {resultado}"4) Permitir repetir con los mismos números
Después de un cálculo, pregunta si quieres usar los mismos números para otra operación. Esto te obliga a pensar el flujo del programa y a evitar pedir datos innecesarios.
Checklist del mini-reto
- El menú se muestra en cada iteración y existe una opción para salir.
- Si el usuario escribe una opción inválida, el programa no se rompe y vuelve a pedir.
- Si el usuario escribe un número inválido, se vuelve a pedir hasta que sea válido.
- La división entre cero se detecta y se informa con un mensaje claro.
- El programa continúa funcionando después de cualquier error.