Hasta ahora hemos visto como las excepciones nos permiten controlar los posibles errores que pueden ocurrir en nuestro código. Sin embargo, dentro de la comunidad de Python tienen otro uso: control de flujo.
Siento que acá todos son expertos, yo tengo que leer las cosas unas 5 veces para entender un poco de lo que habla.
Son palabras que literalmente se que dice, pero no hay una figura imaginativa en mi cerebro, esta totalmente en blanco.
Intente hacer un poco más dinámica esta parte e implementar lo que ha habiamos visto de diccionarios espero les sirva, aún me faltan implementar algunas cosas.
anime = {
'Shounen': 'Naruto',
'Mecha': 'Zoids',
'Vampiros': 'Hellsing',
'Espacio': 'Terra formars',
'Demonios': 'Kimetsu no Yaiba',
'Deportes': 'Capitan Tsubasa',
'Comedia': 'Ranma 1/2',
'Romance': 'Kimi no na wa',
}
defbuscar_en_diccionario(diccionario,llave):try:
return print(diccionario[llave])
except KeyError as e:
print(e)
return (f'{llave} no se encontro en el diccionario')
defactualizar_genero_diccionario(diccionario,llave,valor):
diccionario.update({llave:valor})
return print(f'El diccionario ha sido actualizado \nLos generos son: {diccionario.keys()}')
defeliminar_valor_de_un_genero(diccionario,llave):try:
diccionario_temp = {k:('Sin valor de llave'if diccionario.get(llave)==v else v) for k,v in diccionario.items()}
diccionario.update(diccionario_temp)
return print(f'Hola {diccionario.values()}')
except NameError as e:
print(e)
return print(f'{llave} incorrecta')
defmanipular_dict(diccionario):
print(f'Animes disponibles: {diccionario.values()}')
print('Menu \n1. Buscar genero \n2. Actualizar Genero y anime \n3. Eliminar una anime')
seleccion_menu = int(input('Seleccione un número del menu: '))
if seleccion_menu == 1:
llave = str(input('Seleccione genero que desea buscar: '))
llamar_funcion = buscar_en_diccionario(diccionario,llave)
return manipular_dict(diccionario)
elif seleccion_menu ==2:
llave = str(input('Seleccione genero que desea agregar: '))
valor = str(input('Seleccione anime que desea agregar al genero: '))
llamar_funcion = actualizar_genero_diccionario(diccionario,llave,valor)
return manipular_dict(diccionario)
elif seleccion_menu == 3:
llave = str(input('Seleccione genero del anime que desea eliminar: '))
llamar_funcion = eliminar_valor_de_un_genero(diccionario,llave)
return manipular_dict(diccionario)
else:
print('No se encontró número en el menu')
return manipular_dict(diccionario)
x = manipular_dict(anime)
defbusca_pais(paises, pais):"""
Paises es un diccionario. País es la llave.
Código con el principio EAFP.
"""try:
return paises[pais]
except KeyError:
returnNonedefrun():
paises = {
'Mexico':1,
'Argentina':2,
'Colombia':3
}
pais = input('Ingrese su pais: ')
print(busca_pais(paises, pais))
if __name__ == '__main__':
run()
if pais notin paises.keys():
returnNonereturn paises[pais]
En LBYL, en la función built-in de los diccionarios llamada “keys” se obtiene un iterador, donde se evalúa si existe o no el key, cabe destacar, que en esta implementación me basé en el código escrito en JavaScript.
EAFP es in ingles(es mas fácil pedir perdón que pedir permiso) es mas pythonico
LBYL revisa antes de salta jastripeico
python es un adolescente audaz mientras a java es un viejo precavido
Quise emular la implementacion en JS del estilo LBYL usando la librería pydash (se instala con un pip install pydash desde la consola), y el código terminó así:
# LBYL styleimport pydash
def buscaPais(paises, pais):
result = pydash.objects.find_key(paises, lambda p: p == pais)
returnresult
print(f'LBYL style: {buscaPais(paises, "NombrePais")}')
Por favor si alguien me lo podría explicar de una mejor manera, leí los comentarios en los que trataban de explicarlo pero aún no me queda claro.
Lo que entendí es algo así maso menos:
++ - EAFP( pedir permiso antes que disculpas) ++
Analiza todas las opciones y luego si no la encuentra manda una clave de error, si no hay error arroja la respuesta.
++ - LBYL(revisa antes de saltar) ++
En primer lugar verifica si encuentra el valor pedido en la busqueda, ahí salta el error, pero si verifica que esta el valor buscado ahí pasa a la otra condicional y arroja el resultado.
Encontré este ejemplo que muestra como funciona el **EAFP**
<
# Python
# En lugar de preguntar por algo, se intentar hacerlo.
# Si funciona, muy bien! Sino, se captura el error y se gestiona dela mejor manera
try:
f = open(my_file) # Abramos un archivo queno existe
except NameError ase: # Como no existe, va a haber un errorprint("name is not defined") # Aqui se gestiona el error haciendolo explicito
# El programa no colapsa
with f:
print(f.read())
>
nombre_pais = input(f'Ingrese el nombre de un país de LATAM: ')
defbusca_paises(paises, pais):#Diccionario de países con el método EAFP try:
return paises[pais]
except KeyError:
return f'País no se encuentra en la lista'
gentilicio = {
'Colombia': 'Colombianos',
'Chile':'Chilenos',
'Argentina':'Argentos',
'Brasil':'Brasileiros',
'Venezuela':'Venezolanos'
}
print(busca_paises(gentilicio,nombre_pais))```
defbusca_pais(paises, pais):"""
Paises es un diccionario. Pais es la llave.
Codigo con el principio EAFP.
"""
error = "El dato ingesado no existe"try:
return paises[pais]
except KeyError:
return error
paises = {
'Venezuela': 'Caracas',
'Colombia': 'Bogota',
'Argentina': 'Cordova',
'Canada': 'Ottawa'
}
if __name__ == '__main__':
print(busca_pais(paises, 'Venezuela'))
print(busca_pais(paises, 'Colombia'))
print(busca_pais(paises, 'Italia'))
defbusca_pais(country, pais):"""
paises es un diccionario. pais es la llave.
codigo con el principio EAFP.
"""try:
return paises[pais]
except KeyError:
returnNone
paises = {'España': 'España', 'Ecuador':'Ecuador','Francia':'Francia','Colombia':'Colombia','Rusia':'Rusia','Peru':'Peru'}
pais = 'Francia'
print(busca_pais(paises, pais))
Por lo que entiendo la diferencia es que normalmente en python, se escriben primero las funcionalidades que queremos ejecutar y las probamos, después manejamos la excepción.
En otros lenguajes es preferible primero ejecutar la excepción y después ejecutar lo que queremos hacer.
En la parte que pone “Pais es un diccionario de paises.”, se refiere a que pais es una Key del diccionario paises?
defbusca_pais(paises, pais):"""
Pais es un diccionario de paises.
Codigo con el principio EAFP.
"""try:
return paises[pais]
except KeyError:
returnNone```
Hola compañeros, saludos! Tuve unas cuantas dudas con este tema de “excepciones y manejo de excepciones” la verdad no los entendí muy bien.
Algún consejo que me puedan dar o explicación? ¡Agradecido!
para los que les gusta javascript, utilizar **Object.hasOwn** enves de buscar si la clave esta incluida entre las claves del objeto paises.
otra opcion hasOwnProperty(has un metodo de la instancia de un objeto), esto es peligroso, si el objeto paises tiene una propiedad declarada como *{hasOwnProperty: 1}*, se reemplazara con el que esta en la instancia. Por eso es mejor usar
**Object.hasOwn(objeto, clave):boolean**
```js
/**
* @param {Object} paises
* @param {string} pais
* Paises es un objeto. Pais es la llave
* Codigo con el principio LBYL
*/
function buscaPais(paises, pais) {
if(Object.hasOwn(paises, pais))
return paises[pais];
return null
}
function buscaPais(paises, pais) {
if(paises.hasOwnProperty(pais))
return paises[pais];
return null
}
```
Hola,
Les comparto mi versión del código en Python aplicando lo que hemos visto hasta ahora en el curso:
```js
def busca_pais(paises, pais):
"""Busca la ciudad de un país en el diccionario de países.
Args:
paises (str): Diccionario con los países como llaves.
pais (str): Llave del nombre del país del que se quiere conocer la ciudad.
Returns:
str: Devuelve el valor con la ciudad del país que se busca.
"""
try:
pais = pais.capitalize()
return paises[pais]
except KeyError:
return print("El nombre del país no se encuentra en la base de datos.")
except TypeError:
return print("Por favor ingrese el nombre del país en formato de texto.")
paises = {
'Colombia': 'Bogota',
'España': 'Madrid',
'Alemania': 'Berlin'
}
pais = input('Ingrese el nombre del país del cual quiere hallar la ciudad: ')
resultado = busca_pais(paises, pais)
print(resultado)
```
a ver, pero hasta el moemnto solo se han ejemplificado tipo de excepciones particulaes a funcionalidades especificas, como si fueras a adivinar que tipo de error esperar, y eso esta fantastico si tienes experiencia, pero si no tienes idea del error? aqui la respuesta:
try:
print(x)
except:
print("An exception occurred")
. EAFP (Easier to Ask for Forgiveness than Permission) es un principio de programación que se utiliza en Python para manejar errores y excepciones. En lugar de verificar previamente si una acción es posible, el código intenta realizar la acción y luego maneja cualquier excepción que se produzca. Esto significa que se supone que el código debe “intentar algo y si algo sale mal, manejar la excepción” en lugar de "verificar si algo es posible y luego hacerlo".
.
En Python, el EAFP se ve en el uso del bloque try-except para manejar excepciones en lugar de verificar condiciones previamente. Este enfoque puede hacer que el código sea más conciso y legible, ya que el programador no necesita escribir múltiples declaraciones condicionales.
El principio EAFP se basa en tratar de ejecutar una acción y manejar cualquier excepción que se presente si la acción no se puede completar correctamente. Es decir, se asume que el código funcionará sin errores y se manejan las excepciones que puedan surgir en caso de que algo falle. Este enfoque puede ser más conciso y legible, ya que no se necesitan múltiples comprobaciones antes de realizar una acción. Un ejemplo de EAFP podría ser tratar de abrir un archivo y manejar la excepción si el archivo no existe:
Por otro lado, el principio LBYL se basa en comprobar si es posible realizar una acción antes de intentar ejecutarla. Es decir, se verifica si los datos son válidos antes de realizar una operación que podría generar una excepción. Este enfoque puede ser más seguro, ya que se evitan las excepciones, pero puede generar un código más largo y repetitivo. Un ejemplo de LBYL podría ser comprobar si una lista está vacía antes de intentar acceder a su primer elemento:
lista = [1, 2, 3]if len(lista) > 0:
primer_elemento = lista[0]
else:
print("La lista está vacía.")
Hola comunidad, aquí pueden encontrar diferentes ejercicios sobre este tema, la mayoría en inglés pero no son problema para nosotros que nunca paramos de aprender!!! https://www.w3schools.com/python/python_try_except.asp
Yo interpreto que este uso de Excepciones es para evitar que un error pare de lleno lo que queda de código e impida que siga corriendo el programa. Por eso mediante los metodo EAFP y LBYL podemos hacer que el programa no crashee sino que maneje el error con cierta logica.
Son muy comunes en la programación. No tienen nada de excepcional.
Las excepciones de python normalmente se relacionan con errores de semántica
Se pueden crear excepciones propias
Cuando una excepción no se maneja (unhandled exception), el programa termina en error.
Las excepciones de manejan con los keywords: try, except, finally.
Se pueden utilizar también para ramificar programas.
No deben manejarse de manera silenciosa
Para aventar tu propia excepción utiliza el keyword raise.
✏️ Excepciones comunes (aporte de otro compañero):
ImportError :
una importación falla;
IndexError :
una lista se indexa con un número fuera de rango;
NameError :
se usa una variable desconocida ;
SyntaxError :
el código no se puede analizar correctamente
TypeError :
se llama a una función en un valor de un tipo inapropiado;
ValueError :
se llama a una función en un valor del tipo correcto, pero con un valor inapropiado
✏️ Excepciones y control de flujo
El principio EAFP (easier to ask for forgiveness than permission , es más fácil pedir perdón que permiso, por sus siglas en inglés) es un estilo de programación común en Python en el cual se asumen llaves, índices o atributos son válidos y se captura la excepción si la suposición resulta ser falsa. Es importante resaltar que otros lenguajes de programación favorecen el principio LBYL (look before you leap
, revisa antes de saltar) en el cual el código verifica de manera explícita las precondiciones antes de realizar llamadas.
EAFP
defbusca_pais(paises, pais):"""
Paises es un diccionario. Pais es la llave.
Codigo con el principio EAFP.
"""try:
return paises[pais]
except KeyError:
returnNone
LBYL
/**
* Paises es un objeto. Pais es la llave.
* Codigo con el principio LBYL.
*/functionbuscaPais(paises, pais) {
if(!Object.keys(paises).includes(pais)) {
returnnull;
}
return paises[pais];
}
Como puedes ver, el código de Python accede directamente a la llave y únicamente si dicho acceso falla, entonces se captura la excepción y se provee el código necesario. En el caso de JavaScript, se verifica primero que la llave exista en el objeto y únicamente con posterioridad se accede.
Me identifico mucho más con el principio LBYL, y el principio EAFP lo uso para casos en los que se que puede fallar, como por ejemplo una conexión a una BD.
def busca_pais(paises, pais):
"""
Paises es un diccionario. Pais es la llave.
Codigo con el principio EAFP.
"""
try:
return paises[pais]
except KeyError:
return None
La verdad es que Python tiene un estilo de programacion muy elegante y lo reconozco, pero no se porque me gusta mucho mas JS jaja
Tendra que ver que mis inicios en la programacion fue con C# y JavaScript de algun modo se apega un poquito mas a él.
comidas={
'burger':10,
'salad':9,
'mayo':8,
'fish':7,
'bread':6,
}
comida=input('Escriba la comida que desea para saber su precio ')
defbusComida(comidas,comida):try:
returnprint(comidas[comida])
except KeyError:
returnprint('No existe en el menu')
busComida(comidas, comida)
Hay alguna razón por la que en python no se utilice mas el método LBYL? Ya que he leído que utilizar las excepciones como manejo de flujo no es una buena practica de programación.
EAFP (easier to ask for forgiveness than permission, es más fácil pedir perdón que permiso, por sus siglas en inglés).
LBYL (look before you leap, revisa antes de saltar)
El principio: LBYL (look before you leap, revisa antes de saltar) es muy muy comun y util en APIs en donde necesitamos decirle a quien consume el servicio que fué lo que estuvo mal, lo que lanzó error o lo que envió mal.
Como podria ejecutar este ejemplo , lo trate de hacer de esta manera y no fue posible.
paises = [
{'paises':'colombia'},
{'paises':'peru'}
]
defbusca_pais(country, pais):"""
Paises es un diccionario. Pais es la llave.
Codigo con el principio EAFP.
"""try:
return paises[pais]
country = (paises[colombia])
except KeyError:
returnNone```
Algun experto "Pythonico" que me pueda ayudar.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?