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.
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
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.