Excepciones y control de flujo
Clase 29 de 31 • Curso de Introducción al Pensamiento Computacional con Python
Contenido del curso
Clase 29 de 31 • Curso de Introducción al Pensamiento Computacional con Python
Contenido del curso
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.
En este momento ya debes estar familiarizado con las estructuras de control flujo que ofrece Python (if... elif...else); entonces, ¿por qué es necesaria otra modalidad para controlar el flujo? Una razón muy específica: 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).
El principio EAFP es un estilo de programación común en Python en el cual se asumen llaves, índices o atributos 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.
Veamos ambos estilos:
# Python 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
// Javascript /** * Paises es un objeto. Pais es la llave. * Codigo con el principio LBYL. */ function buscaPais(paises, pais) { if(!Object.keys(paises).includes(pais)) { return null; } 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.
Es importante resaltar que ambos estilos pueden utilizarse en Python, pero el estilo EAFP es mucho más "pythonico".
Rafael Carpio
Nicolás Ponce Vera
Ivan Ezequiel Mazzalay
Gustavo Ulises Lira Reyes
Pablo Andres Onofre Riascos
Andres Felipe Noguera Escandon
Manuel Alejandro Hermoso
Isay Humberto Lucas Hernandez
Manuel Alejandro Hermoso
Braulio Alberto Bueno Pabon
Lorenzo Enrique Piñango Cerezo
Wilson Delgado
José Contreras
Marcos Monteverde
Carmen Sánchez Salgado
Juan Manuel Roa Mejia
ALDO MATUS MARTINEZ
Mauricio Obe
ALDO MATUS MARTINEZ
Esteban Ramírez García
Esteban Ramírez García
Juan David Cepeda López
Daniel Libardo Diaz Gonzalez
Carlos Iván Cortés Cruz
Arturo Baduna
Edgar Norbey Usnas Jambuel
Daniel Alejandro Cumaco Robayo
Nicolás Cabrera
Alejandro Barrios
Alejo Lemos
Jose Ramon Moreno Sanchez
DAVID LEONARDO ALFONSO BENAVIDES
Elmer Padilla Espinoza
David Jonatan Mora Bejarano
Carli Code
Diego Astudillo
Leandro Tenjo
Abril Rios
Luis Fernando Pedroza Taborda
Gerson Montenegro
Brandy Luis Lopez Pacheco
Clayton Jhordan Iliquin Zavaleta
Marisol Catari Choquehuanca
Ignacio Crespo
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.
Así empieza la curva de aprendizaje para cualquier tema nuevo. Estoy en la misma situación pero por experiencias pasadas sé que se vuelve más sencillo con la práctica. Ánimo!
Tranquilo Rafael, nos ha pasado a todos.. yo hace un par de años que empecé a meterme al tema del software por mi cuenta pero nunca pude dedicarme realmente como ahora y te puedo asegurar que he aprendido un montón, he tenido dudas y he tenido por ahí que recurrir a otras fuentes o al lápiz y al papel mas de una vez.. ánimos, a no bajar los brazos que con tiempo, estudio y práctica todo se aprende. Qué es lo que no entiendes? Comentame así te ayudo a entenderlo.
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', } def buscar_en_diccionario(diccionario,llave): try: return print(diccionario[llave]) except KeyError as e: print(e) return (f'{llave} no se encontro en el diccionario') def actualizar_genero_diccionario(diccionario,llave,valor): diccionario.update({llave:valor}) return print(f'El diccionario ha sido actualizado \nLos generos son: {diccionario.keys()}') def eliminar_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') def manipular_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)
Intentar hacer el mismo programa con switch(maneja menor las opciones) y te quedara perfecto, gracias compañero.
muy interesante.
Digamos que en un buffet
El principio EAFP
El principio LBYL
Creo que la analogía del buffet se aleja un poco del significado de EAFP y LBYL.
Estos estilos permiten "asumir" que un error podría ocurrir. En este caso, al buscar con una llave un valor en un diccionario/objeto.
Por ejemplo, asumiendo que el diccionario/objeto tiene 150 elementos (enumerados del 1 al 150) y por "accidente" se envía un 9999, la función está preparada para decir "Oye viejo, tu llave está muy bonita y todo pero no tengo un valor de país con dicha llave"; a simplemente dejar de funcionar.
**Es más fácil pedir perdón: **(Desarrollador porque agregaste esa excepción?! Pero bueno, nos salvó el día tu suposición)
A pedir permiso: (Oiga jefecito, me da chance de escribir este control de excepción? :( ).
Saludos!
Interesante, me dejas pensando como lo podría aplicar a buffet :)
EAFP:
try: x = my_dict["key"] except KeyError: # handle missing key
LBYL:
if "key" in my_dict: x = my_dict["key"] else: # handle missing key
La versión LBYL tiene que buscar la clave dentro del diccionario dos veces y también podría considerarse un poco menos legible.
Gracias :)
Para complementar https://www.youtube.com/watch?v=ph1DuXvTrIw
Gracias bro!
gracias
Pythonico!
Hola Carmen, espero te encuentres muy bien.
Me parece curioso tu código ya que noté que usaste el estilo EAFP para la función busca_pais() y también usaste implícitamente el estilo LBYL para poder imprimir el retorno.
Gran ejemplo para entenderlo :D
Script completo EAFP en Python :snake: :smiley:
def busca_pais(paises, pais): """ Paises es un diccionario. País es la llave. Código con el principio EAFP. """ try: return paises[pais] except KeyError: return None def run(): paises = { 'Mexico':1, 'Argentina':2, 'Colombia':3 } pais = input('Ingrese su pais: ') print(busca_pais(paises, pais)) if __name__ == '__main__': run()
le falto una coma al 3 me sirvio para practicar tu codigo, gracias!
Me alegra esa es la intención, poder ayudar :smiley:
Como dice la info, el estilo EAFP es más pythonico, sin embargo, para efectos de ilustración creo que esto podría servir
EAFP
try: return paises[pais] except KeyError: return None
LBYL
if pais not in paises.keys(): return None return 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.
Cuando digo "donde se valúa si existe o no el key", me refiero a esta implementación del método en el if que se puede observar, no me refiero a que la función realiza la evaluación.
Python es muy elegante, se tenia que decir y se dijo.
De acuerdo!
Ohh siii
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
Me quedo mas claro con este comentario :)
Java es horrible, mas feo que C jajaja
Me parece mucho mas fácil el estilo EAFP, punto para Python 😂😂
realmente en Javascript el codigo no esta mal, pero parece hecho por alguien no especializado en javascript. la representacion real seria algo asi:
function buscaPais(paises, pais) { return paises[pais] }
si el pais existe, lo retorna, de lo contrario devuelve null.
es verdad Alejandro me parecio muy raro ese codigo en js jajajaja
pythonico :)
jajajaja es más fácil pedir perdón que permiso
Me gusto el uso de la palabra "pythonico"
yo soy programador de C# se me hace más natural el estilo de LBYL
Grace Hopper _ «Si es una buena idea, continuad y llevadla a término. Es mucho más fácil pedir disculpas que conseguir el permiso necesario»_
pregunta para puntos
Realmente quiere preguntar algo?
O solo intenta subir el platzi rank?
. De ser así, es mucho fácil otras cosas como
… En cada una de las clases vi la misma “pregunta”, (comentario diría yo) Hay muchas formas. Pero el spam solo te da mala imagen.
Realmente si queres subir puntos hacelo sin trampa además el único perjudicado a la larga serás vos. 😐
La verdad no conocia sobre este estilo de programacion, Python esta lleno de sorpresas.
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 style import pydash def buscaPais(paises, pais): result = pydash.objects.find_key(paises, lambda p: p == pais) return result print(f'LBYL style: {buscaPais(paises, "NombrePais")}')
Excelente!
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.
Clayton: Mi explicación en palabras simples, veamos si te resulta más sencillo.
En ambos casos, no hay obligatoriedad de usarlos, solamente son 'estilos' saludables para manejar excepciones.
Gracias @marisolcatari por la explicación! Yo también tenía la misma duda :D