diff --git a/manejo_excepciones.md b/manejo_excepciones.md new file mode 100644 index 0000000..720db2a --- /dev/null +++ b/manejo_excepciones.md @@ -0,0 +1,94 @@ +### Manejo de Excepciones en Python + +El manejo de excepciones es una parte fundamental de la programación para hacer que tu código sea más robusto y fácil de mantener. En Python, puedes usar bloques `try-except` para capturar y manejar errores. Aquí te explico los puntos más importantes para que aprendas a usar correctamente las excepciones. + +#### 1. **Evita silenciar las excepciones con `except:` sin especificar el error** +Siempre debes capturar errores específicos, en lugar de usar un bloque genérico como `except:`. Esto puede ocultar errores importantes y hacer que el programa continúe en un estado inesperado. Por ejemplo, si solo capturas una excepción general, podrías estar ignorando fallos graves en tu código, lo que dificultaría encontrar el problema. + +**Incorrecto**: +```python +try: + resultado = 10 / 0 +except: + print("*ERROR* Algo salió mal.") +``` +En este ejemplo, cualquier error, no solo la división por cero, sería capturado y el mensaje no te daría información suficiente. + +**Correcto**: +```python +try: + resultado = 10 / 0 +except ZeroDivisionError: + print("*ERROR* No se puede dividir por cero.") +``` +Aquí, solo capturamos un error específico, lo que nos permite dar un mensaje claro y preciso. + +#### 2. **Capturar múltiples excepciones en una sola línea** +Puedes manejar múltiples tipos de errores en una sola línea usando una tupla. Esto es útil cuando sabes que pueden ocurrir varios tipos de errores y quieres manejarlos de la misma forma. + +**Ejemplo**: +```python +try: + resultado = float(input("Introduce un número: ")) / 0 +except (ZeroDivisionError, ValueError) as e: + print(f"*ERROR* {e}") +``` +En este ejemplo, capturamos tanto el error de división por cero como el error de valor incorrecto en la entrada de una sola vez. + +#### 3. **Lanzar excepciones con `raise`** +A veces, querrás lanzar tus propias excepciones cuando ocurra una condición específica en tu programa. Para esto se utiliza la instrucción `raise`. Puedes lanzar excepciones integradas como `ValueError` o crear tus propias excepciones. + +**Ejemplo con `raise`**: +```python +def validar_edad(edad): + if edad < 0: + raise ValueError("La edad no puede ser negativa.") + elif edad > 120: + raise ValueError("La edad no puede ser mayor a 120.") + return edad + +try: + validar_edad(-5) +except ValueError as e: + print(e) +``` +En este caso, lanzamos un `ValueError` si la edad es inválida, y luego lo capturamos con un bloque `try-except`. + +#### 4. **Uso de `else` en `try-except`** +El bloque `else` se ejecuta solo si no ocurre ninguna excepción. Esto es útil para ejecutar código solo cuando todo ha ido bien y no se ha lanzado ningún error. + +**Ejemplo**: +```python +try: + resultado = 10 / 2 +except ZeroDivisionError: + print("Error en la división.") +else: + print(f"El resultado es: {resultado}") +``` +Si no ocurre ningún error en la división, el bloque `else` imprimirá el resultado de la operación. + +#### 5. **Uso de `finally` para tareas de limpieza** +El bloque `finally` siempre se ejecuta, independientemente de si ocurrió una excepción o no. Esto es útil para liberar recursos o asegurarte de que algo ocurra, como cerrar un archivo o desconectar una base de datos. + +**Ejemplo con `finally`**: +```python +def dividir(num1, num2): + try: + resultado = num1 / num2 + return resultado + except ZeroDivisionError: + print("*ERROR* No se puede dividir por cero.") + finally: + print("Operación finalizada.") +``` +En este caso, el bloque `finally` se ejecutará siempre, incluso si hay un error en la división, lo que puede ser útil para tareas de limpieza. + +### Conclusión: +El manejo adecuado de excepciones te permitirá escribir código más robusto y seguro. Recuerda siempre: +- Capturar excepciones específicas. +- Usar `else` para separar el código de éxito del manejo de errores. +- Usar `raise` para lanzar tus propias excepciones cuando sea necesario. +- Usar `finally` para liberar recursos o realizar tareas críticas. + +Al seguir estas prácticas, tus programas serán más fáciles de mantener y menos propensos a fallos inesperados. \ No newline at end of file diff --git a/src/ej23_1.py b/src/ej23_1.py new file mode 100644 index 0000000..1dd25c8 --- /dev/null +++ b/src/ej23_1.py @@ -0,0 +1,40 @@ +""" +Ej 2.3.1 - Escribir un programa que pregunte al usuario su edad y muestre por pantalla todos los años que ha cumplido (desde 1 hasta su edad). +Extra1: Lanzar excepciones con mensajes específicos si la edad es negativa, igual a 0 o superior a 125 años. +Extra2: Evita mostrar un mensaje en inglés. +""" + +def pedir_edad() -> int: + edad = None + while edad is None: + try: + edad = int(input("Introduce tu edad: ")) + if not (1 <= edad <= 125): + if edad < 1: + raise ValueError("La edad debe ser un número positivo.") + if edad == 0: + raise ValueError("La edad debe ser un número positivo mayor que cero.") + if edad > 125: + raise ValueError("La edad debe ser un número inferior o igual a 125.") + edad = None + except ValueError as e: + if edad is None: + print(f"*ERROR* El número introducido no es un entero válido. Inténtalo de nuevo.") + else: + print(f"*ERROR* {e}. Inténtalo de nuevo.") + return edad + + +def mostrar_anios_cumplidos(edad: int): + for i in range(1, edad + 1): + print(i) + + +def main(): + edad = pedir_edad() + print(f"Has cumplido los siguientes años:") + mostrar_anios_cumplidos(edad) + + +if __name__ == "__main__": + main() diff --git a/src/ej23_2.py b/src/ej23_2.py new file mode 100644 index 0000000..54bce9e --- /dev/null +++ b/src/ej23_2.py @@ -0,0 +1,32 @@ +""" +Ej 2.3.2 - Escribir un programa que pida al usuario un número entero positivo y muestre por pantalla todos los números impares desde 1 hasta ese número separados por comas. +""" +def pedir_numero_positivo() -> int: + numero = None + while numero is None: + try: + numero = int(input("Introduce un número entero positivo: ")) + if numero <= 0: + numero = None + raise ValueError("El número debe ser positivo.") + except ValueError as e: + print(f"*ERROR* {e}. Inténtalo de nuevo.") + return numero + + +def obtener_impares(numero: int) -> str: + impares = "" + for i in range(1, numero + 1, 2): + impares += f"{i}, " + + return impares[:-2] + + +def main(): + numero = pedir_numero_positivo() + print(f"Números impares desde 1 hasta {numero}:") + print(obtener_impares(numero)) + + +if __name__ == "__main__": + main() diff --git a/src/ej23_3.py b/src/ej23_3.py new file mode 100644 index 0000000..a413682 --- /dev/null +++ b/src/ej23_3.py @@ -0,0 +1,36 @@ +""" +Ej 2.3.3 - Escribir un programa que pida al usuario un número entero positivo y muestre por pantalla la cuenta atrás desde ese número hasta cero separados por comas. Deberá solicitar el número hasta introducir uno correcto. +Extra: usa el parámetro "end" en "print" para mostrar la cuenta atrás, directamente sin usar una cadena de caracteres, en la función mostrar_cuenta_atras(numero: int) +""" + +def pedir_numero_positivo() -> int: + numero = None + while numero is None: + try: + valor = int(input("Introduce un número entero positivo: ")) + if valor <= 0: + raise ValueError("El número debe ser positivo.") + numero = valor + except ValueError as e: + print(f"*ERROR* {e}. Inténtalo de nuevo.") + return numero + + +def mostrar_cuenta_atras(numero: int): + primero = True + for i in range(numero, -1, -1): + if primero: + print(i, end="") + primero = False + else: + print(f", {i}", end="") + + +def main(): + numero = pedir_numero_positivo() + print(f"Cuenta atrás desde {numero} hasta cero:") + mostrar_cuenta_atras(numero) + + +if __name__ == "__main__": + main() diff --git a/src/ej23_4.py b/src/ej23_4.py new file mode 100644 index 0000000..b890163 --- /dev/null +++ b/src/ej23_4.py @@ -0,0 +1,23 @@ +""" +Ej 2.3.4 - Escribir un programa que pida al usuario un número entero, si la entrada no es correcta, mostrará el mensaje "La entrada no es correcta" y lanzará la excepción capturada. +""" + +def pedir_entero() -> int: + try: + numero = int(input("Introduce un número entero: ")) + return numero + except ValueError: + print("La entrada no es correcta") + raise # Vuelve a lanzar la excepción capturada + + +def main(): + try: + numero = pedir_entero() + print(f"El número introducido es: {numero}") + except ValueError: + print("*ERROR* Se ha capturado la excepción ValueError.") + + +if __name__ == "__main__": + main() diff --git a/src/ej23_5.py b/src/ej23_5.py new file mode 100644 index 0000000..6833b3a --- /dev/null +++ b/src/ej23_5.py @@ -0,0 +1,23 @@ +""" +Ej 2.3.5 - Escribir un programa que solicite una contraseña, y si no coincide con la que se tiene, lance la excepción NameError con el mensaje, "Incorrect Password!!". +""" + +PASSWORD = "1234" + +def pedir_contrasena() -> str: + contrasena = input("Password? ") + if contrasena != PASSWORD: + raise NameError("Incorrect Password!!") + return contrasena + + +def main(): + try: + pedir_contrasena() + print("Yeah! you know your own password!") + except NameError as e: + print(e) + + +if __name__ == "__main__": + main() diff --git a/src/excepciones_actividad01_v1.py b/src/excepciones_actividad01_v1.py new file mode 100644 index 0000000..7c2bf4f --- /dev/null +++ b/src/excepciones_actividad01_v1.py @@ -0,0 +1,39 @@ + +def pedir_numero(msj: str) -> float: + numero = None + while numero is None: + try: + numero = float(input(msj).strip().replace(",", ".")) + except ValueError: + print("*ERROR* El número introducido no es válido!") + except Exception as e: + print(f"*ERROR* Se ha producido un error: {e}") + + return numero + + +def dividir(num1, num2) -> float: + resultado = None + try: + resultado = num1 / num2 + except ZeroDivisionError: + print("*ERROR* No es posible la división por cero!") + except Exception as e: + print(f"*ERROR* Se ha producido un error: {e}") + + return resultado + + +def main(): + print("Vamos a realizar la división de dos números...") + num1 = pedir_numero("Introduzca el número que desea dividir: ") + num2 = pedir_numero("Introduzca el divisor del número anterior: ") + + resultado = dividir(num1, num2) + + if resultado is not None: + print("La división es {:.2f}".format(resultado)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/excepciones_actividad01_v2.py b/src/excepciones_actividad01_v2.py new file mode 100644 index 0000000..ed78894 --- /dev/null +++ b/src/excepciones_actividad01_v2.py @@ -0,0 +1,38 @@ + +def pedir_numero(msj: str) -> float: + numero = None + while numero is None: + try: + numero = float(input(msj).strip().replace(",", ".")) + except ValueError: + print("*ERROR* El número introducido no es válido!") + except Exception as e: + print(f"*ERROR* Se ha producido un error: {e}") + + return numero + + +def dividir(num1, num2) -> float: + if num2 == 0: + raise ZeroDivisionError("*ERROR* No es posible la división por cero!") + + return num1 / num2 + + +def main(): + print("Vamos a realizar la división de dos números...") + num1 = pedir_numero("Introduzca el número que desea dividir: ") + num2 = pedir_numero("Introduzca el divisor del número anterior: ") + + try: + resultado = dividir(num1, num2) + except ZeroDivisionError as e: + print(e) + except Exception as e: + print(f"*ERROR* Se ha producido un error: {e}") + else: + print(f"La división es: {resultado:.2f}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/excepciones_otros1.py b/src/excepciones_otros1.py new file mode 100644 index 0000000..7e350c1 --- /dev/null +++ b/src/excepciones_otros1.py @@ -0,0 +1,21 @@ + +def dividir(num1: float, num2: float) -> float: + try: + resultado = num1 / num2 + return resultado + except ZeroDivisionError: + print("*ERROR* No se puede dividir por cero.") + finally: + print("Finalizando la operación de división.") + + +def main(): + num1 = 10 + num2 = 0 + resultado = dividir(num1, num2) + if resultado is not None: + print(f"El resultado de la división es: {resultado}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/excepciones_otros2.py b/src/excepciones_otros2.py new file mode 100644 index 0000000..b190ede --- /dev/null +++ b/src/excepciones_otros2.py @@ -0,0 +1,20 @@ + +def validar_edad(edad: int): + if edad < 0: + raise ValueError("*ERROR* La edad no puede ser negativa.") + elif edad > 120: + raise ValueError("*ERROR* La edad no puede ser mayor a 120.") + return edad + + +def main(): + try: + edad = int(input("Introduce tu edad: ")) + validar_edad(edad) + print(f"Tu edad es: {edad}") + except ValueError as e: + print(e) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/excepciones_otros3.py b/src/excepciones_otros3.py new file mode 100644 index 0000000..b342a4c --- /dev/null +++ b/src/excepciones_otros3.py @@ -0,0 +1,27 @@ + +class MiError(Exception): + """Excepción personalizada para errores específicos.""" + def __init__(self, mensaje): + self.mensaje = mensaje + super().__init__(self.mensaje) + + +def comprobar_valor(valor): + if valor < 0: + raise MiError("El valor no puede ser negativo.") + else: + print("El valor es válido:", valor) + + +def main(): + try: + numero = int(input("Introduce un número: ")) + comprobar_valor(numero) + except MiError as e: + print(f"*ERROR* {e}") + except ValueError: + print("*ERROR* El valor debe ser un número entero.") + + +if __name__ == "__main__": + main()