Skip to content

Commit

Permalink
Ejercicios y explicaciones de Captura de Excepciones
Browse files Browse the repository at this point in the history
  • Loading branch information
dcsibon committed Oct 21, 2024
1 parent ab86651 commit 61c240a
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 0 deletions.
94 changes: 94 additions & 0 deletions manejo_excepciones.md
Original file line number Diff line number Diff line change
@@ -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.
40 changes: 40 additions & 0 deletions src/ej23_1.py
Original file line number Diff line number Diff line change
@@ -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()
32 changes: 32 additions & 0 deletions src/ej23_2.py
Original file line number Diff line number Diff line change
@@ -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()
36 changes: 36 additions & 0 deletions src/ej23_3.py
Original file line number Diff line number Diff line change
@@ -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()
23 changes: 23 additions & 0 deletions src/ej23_4.py
Original file line number Diff line number Diff line change
@@ -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()
23 changes: 23 additions & 0 deletions src/ej23_5.py
Original file line number Diff line number Diff line change
@@ -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()
39 changes: 39 additions & 0 deletions src/excepciones_actividad01_v1.py
Original file line number Diff line number Diff line change
@@ -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()
38 changes: 38 additions & 0 deletions src/excepciones_actividad01_v2.py
Original file line number Diff line number Diff line change
@@ -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()
21 changes: 21 additions & 0 deletions src/excepciones_otros1.py
Original file line number Diff line number Diff line change
@@ -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()
20 changes: 20 additions & 0 deletions src/excepciones_otros2.py
Original file line number Diff line number Diff line change
@@ -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()
Loading

0 comments on commit 61c240a

Please sign in to comment.