Diferències
Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
info:cursos:netacad:python:pe1m4 [21/06/2022 10:23] – mate | info:cursos:netacad:python:pe1m4 [21/06/2022 10:27] (actual) – mate | ||
---|---|---|---|
Línia 6: | Línia 6: | ||
* [[info: | * [[info: | ||
* Tuplas y su propósito: construcción y uso de tuplas. | * Tuplas y su propósito: construcción y uso de tuplas. | ||
- | * Diccionarios y su propósito: construcción y uso de diccionarios. | + | |
- | * Introducción a las excepciones en Python. | + | |
+ | | ||
+ | | ||
- | |||
- | |||
- | == ¿Qué es un diccionario? | ||
- | El **diccionario** es otro tipo de estructura de datos de Python. No **es una secuencia** (pero puede adaptarse fácilmente a un procesamiento secuencial) y además es **mutable**. | ||
- | |||
- | Para explicar lo que es un diccionario en Python, es importante comprender de manera literal lo que es un diccionario. | ||
- | |||
- | Un diccionario en Python funciona de la misma manera que **un diccionario bilingüe**. Por ejemplo, se tiene la palabra en español " | ||
- | |||
- | En el mundo de Python, la palabra que se esta buscando se denomina **clave(key)**. La palabra que se obtiene del diccionario es denominada **valor**. | ||
- | |||
- | Esto significa que un diccionario es un conjunto de pares de **claves y valores**. Nota: | ||
- | |||
- | * Cada clave debe de ser única. No es posible tener una clave duplicada. | ||
- | * Una clave puede ser un tipo de dato de cualquier tipo: puede ser un número (entero o flotante), o incluso una cadena. | ||
- | * Un diccionario no es una lista. Una lista contiene un conjunto de valores numerados, mientras que un diccionario almacena pares de valores. | ||
- | * La función len() aplica también para los diccionarios, | ||
- | * Un diccionario es una herramienta de un solo sentido. Si fuese un diccionario español-francés, | ||
- | |||
- | == ¿Cómo crear un diccionario? | ||
- | Si deseas asignar algunos pares iniciales a un diccionario, | ||
- | |||
- | <code python> | ||
- | dictionary = {" | ||
- | phone_numbers = {' | ||
- | empty_dictionary = {} | ||
- | |||
- | print(dictionary) | ||
- | print(phone_numbers) | ||
- | print(empty_dictionary) | ||
- | </ | ||
- | |||
- | En este primer ejemplo, el diccionario emplea claves y valores las cuales ambas son cadenas. En el segundo, las claves con cadenas pero los valores son enteros. El orden inverso (claves → números, valores → cadenas) también es posible, así como la combinación número a número. | ||
- | |||
- | La lista de todos los pares es **encerrada con llaves**, mientras que los pares son **separados por comas**, y **las claves y valores por dos puntos**. | ||
- | |||
- | El primer diccionario es muy simple, es un diccionario Español-Francés. El segundo es un directorio telefónico muy pequeño. | ||
- | |||
- | Los diccionarios vacíos son construidos por **un par vacío de llaves** - nada inusual. | ||
- | |||
- | |||
- | El diccionario entero se puede imprimir con una invocación a la función print(). El fragmento de código puede producir la siguiente salida: | ||
- | < | ||
- | {' | ||
- | {' | ||
- | {} | ||
- | </ | ||
- | ¿Has notado que el orden de los pares impresos es diferente a la asignación inicial?, ¿Qué significa esto? | ||
- | |||
- | Primeramente, | ||
- | |||
- | NOTA: En Python 3.6x los diccionarios se han convertido en colecciones ordenadas de manera predeterminada. Tu resultado puede variar dependiendo en la versión de Python que se este utilizando. | ||
- | |||
- | == ¿Cómo utilizar un diccionario? | ||
- | Si deseas obtener cualquiera de los valores, debes de proporcionar una clave válida: | ||
- | <code python> | ||
- | print(dictionary[' | ||
- | print(phone_numbers[' | ||
- | </ | ||
- | |||
- | El obtener el valor de un diccionario es semejante a la indexación, | ||
- | |||
- | Nota: | ||
- | * Si una clave es una cadena, se tiene que especificar como una cadena. | ||
- | * Las claves son sensibles a las mayúsculas y minúsculas: | ||
- | |||
- | El fragmento de código da las siguientes salidas: | ||
- | < | ||
- | chat | ||
- | 5557654321 | ||
- | </ | ||
- | |||
- | Ahora algo muy importante: **No se puede utilizar una clave que no exista**. Hacer algo como lo siguiente: | ||
- | <code python> | ||
- | print(phone_numbers[' | ||
- | </ | ||
- | Provocará un error de ejecución. Inténtalo. | ||
- | |||
- | Afortunadamente, | ||
- | |||
- | El siguiente código busca de manera segura palabras en francés: | ||
- | <code python> | ||
- | dictionary = {" | ||
- | words = [' | ||
- | |||
- | for word in words: | ||
- | if word in dictionary: | ||
- | print(word, " | ||
- | else: | ||
- | print(word, "no está en el diccionario" | ||
- | </ | ||
- | |||
- | La salida del código es la siguiente: | ||
- | < | ||
- | gato -> chat | ||
- | león no está en el diccionario | ||
- | caballo -> cheval | ||
- | </ | ||
- | |||
- | Nota: Cuando escribes una expresión grande o larga, puede ser una buena idea mantenerla alineada verticalmente. Así es como puede hacer que el código sea más legible y más amigable para el programador, | ||
- | |||
- | <code python> | ||
- | # Ejemplo 1: | ||
- | dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | # Ejemplo 2: | ||
- | phone_numbers = {' | ||
- | ' | ||
- | } | ||
- | </ | ||
- | |||
- | Este tipo de formato se llama **sangría francesa**. | ||
- | |||
- | == ¿Cómo utilizar un diccionario? | ||
- | ¿Pueden los diccionarios ser **examinados** utilizando el bucle for, como las listas o tuplas? | ||
- | |||
- | No y si. | ||
- | |||
- | No, porque un diccionario **no es un tipo de dato secuencial** - el bucle '' | ||
- | |||
- | Si, porque hay herramientas simples y muy efectivas que pueden **adaptar cualquier diccionario a los requerimientos del bucle** '' | ||
- | |||
- | El primero de ellos es un método denominado **keys()**, el cual es parte de todo diccionario. El método retorna o regresa una lista de todas las claves dentro del diccionario. Al tener una lista de claves se puede acceder a todo el diccionario de una manera fácil y útil. | ||
- | |||
- | A continuación se muestra un ejemplo: | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | for key in dictionary.keys(): | ||
- | print(key, " | ||
- | </ | ||
- | |||
- | El código produce la siguiente salida: | ||
- | < | ||
- | gato -> chat | ||
- | perro -> chien | ||
- | caballo -> cheval | ||
- | </ | ||
- | |||
- | == La función sorted() | ||
- | ¿Deseas que la salida este ordenada? Solo hay que agregar al bucle for lo siguiente: | ||
- | <code python> | ||
- | for key in sorted(dictionary.keys()): | ||
- | </ | ||
- | |||
- | La función **sorted()** hará su mejor esfuerzo y la salida será la siguiente: | ||
- | |||
- | < | ||
- | caballo -> cheval | ||
- | gato -> chat | ||
- | perro -> chien | ||
- | </ | ||
- | |||
- | == ¿Cómo utilizar un diccionario? | ||
- | Otra manera de hacerlo es utilizar el método **items()**. Este método **regresa una lista de tuplas** (este es el primer ejemplo en el que las tuplas son mas que un ejemplo de si mismas) **donde cada tupla es un par de cada clave con su valor**. | ||
- | |||
- | Así es como funciona: | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | for index, value in dictionary.items(): | ||
- | print(index, | ||
- | </ | ||
- | |||
- | Nota la manera en que la tupla ha sido utilizada como una variable del bucle for. | ||
- | |||
- | El ejemplo imprime lo siguiente: | ||
- | < | ||
- | gato -> chat | ||
- | perro -> chien | ||
- | caballo -> cheval | ||
- | </ | ||
- | |||
- | También existe un método denominado **values()**, | ||
- | |||
- | Este es un ejemplo sencillo: | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | for value in dictionary.values(): | ||
- | print(value) | ||
- | </ | ||
- | |||
- | Como el diccionario no es capaz de automáticamente encontrar la clave de un valor dado, el rol de este método es algo limitado. | ||
- | |||
- | Esta es la salida esperada: | ||
- | < | ||
- | chat | ||
- | chien | ||
- | cheval | ||
- | </ | ||
- | |||
- | == ¿Cómo utilizar un diccionario? | ||
- | El asignar un nuevo valor a una clave existente es sencillo, debido a que los diccionarios son completamente **mutables**, | ||
- | |||
- | Se va a reemplazar el valor " | ||
- | |||
- | <code python> | ||
- | dictionary = {' | ||
- | |||
- | dictionary[' | ||
- | print(dictionary) | ||
- | </ | ||
- | |||
- | La salida es: | ||
- | < | ||
- | {' | ||
- | </ | ||
- | |||
- | == Agregando nuevas claves | ||
- | El agregar una nueva clave con su valor a un diccionario es tan simple como cambiar un valor. Solo se tiene que asignar un valor a una nueva **clave que no haya existido antes**. | ||
- | |||
- | Nota: este es un comportamiento muy diferente comparado a las listas, las cuales no permiten asignar valores a índices no existentes. | ||
- | |||
- | A continuación se agrega un par nuevo al diccionario, | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | dictionary[' | ||
- | print(dictionary) | ||
- | </ | ||
- | El ejemplo muestra como salida: | ||
- | < | ||
- | {' | ||
- | </ | ||
- | Note: También es posible insertar un elemento al diccionario utilizando el método **update()**, | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | dictionary.update({" | ||
- | print(dictionary) | ||
- | </ | ||
- | |||
- | == Eliminado una clave | ||
- | ¿Puedes deducir como eliminar una clave de un diccionario? | ||
- | |||
- | Nota: al eliminar la clave también se **removerá el valor asociado. Los valores no pueden existir sin sus claves**. | ||
- | |||
- | Esto se logra con la instrucción **del**. | ||
- | |||
- | A continuación un ejemplo: | ||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | del dictionary[' | ||
- | print(dictionary) | ||
- | </ | ||
- | |||
- | Nota: **el eliminar una clave no existente, provocará un error**. | ||
- | |||
- | El ejemplo da como salida: | ||
- | < | ||
- | {' | ||
- | </ | ||
- | |||
- | === EXTRA | ||
- | |||
- | Para eliminar el ultimo elemento de la lista, se puede emplear el método **popitem()**: | ||
- | |||
- | <code python> | ||
- | dictionary = {" | ||
- | |||
- | dictionary.popitem() | ||
- | print(dictionary) | ||
- | </ | ||
- | |||
- | En versiones anteriores de Python, por ejemplo, antes de la 3.6.7, el método **popitem()** elimina un elemento al azar del diccionario. | ||
- | |||
- | == Las tuplas y los diccionarios pueden trabajar juntos | ||
- | Se ha preparado un ejemplo sencillo, mostrando como las tuplas y los diccionarios pueden trabajar juntos. | ||
- | |||
- | Imaginemos el siguiente problema: | ||
- | |||
- | Necesitas un programa para calcular los promedios de tus alumnos. | ||
- | El programa pide el nombre del alumno seguido de su calificación. | ||
- | Los nombres son ingresados en cualquier orden. | ||
- | El ingresar un nombre vacío finaliza el ingreso de los datos (nota 1: ingresar una puntuación vacía generará la excepción ValueError, pero no te preocupes por eso ahora, verás cómo manejar tales casos cuando hablemos de excepciones en el segundo parte de la serie del curso). | ||
- | Una lista con todos los nombre y el promedio de cada alumno debe ser mostrada al final. | ||
- | <sxh python> | ||
- | school_class = {} | ||
- | |||
- | while True: | ||
- | name = input(" | ||
- | if name == '': | ||
- | break | ||
- | | ||
- | score = int(input(" | ||
- | if score not in range(0, 11): | ||
- | break | ||
- | | ||
- | if name in school_class: | ||
- | school_class[name] += (score,) | ||
- | else: | ||
- | school_class[name] = (score,) | ||
- | | ||
- | for name in sorted(school_class.keys()): | ||
- | adding = 0 | ||
- | counter = 0 | ||
- | for score in school_class[name]: | ||
- | adding += score | ||
- | counter += 1 | ||
- | print(name, ":", | ||
- | </ | ||
- | |||
- | Ahora se analizará línea por línea: | ||
- | * Línea 1: crea un diccionario vacío para ingresar los datos: el nombre del alumno es empleado como clave, mientras que todas las calificaciones asociadas son almacenadas en una tupla (la tupla puede ser el valor de un diccionario, | ||
- | * Línea 3: se ingresa a un bucle " | ||
- | * Línea 4: se lee el nombre del alumno aquí. | ||
- | * Línea 5-6: si el nombre es una cadena vacía (), salimos del bucle. | ||
- | * Línea 8: se pide la calificación del estudiante (un valor entero en el rango del 1-10). | ||
- | * Línea 9-10: si la puntuación ingresada no está dentro del rango de 0 a 10, se abandona el bucle. | ||
- | * Línea 12-13: si el nombre del estudiante ya se encuentra en el diccionario, | ||
- | * Línea 14-15: si el estudiante es nuevo (desconocido para el diccionario), | ||
- | * Línea 17: se itera a través de los nombres ordenados de los estudiantes. | ||
- | * Línea 18-19: inicializa los datos necesarios para calcular el promedio (sum y counter). | ||
- | * Línea 20-22: se itera a través de la tupla, tomado todas las calificaciones subsecuentes y actualizando la suma junto con el contador. | ||
- | * Línea 23: se calcula e imprime el promedio del alumno junto con su nombre. | ||
- | |||
- | Este es un ejemplo del programa: | ||
- | < | ||
- | Ingresa el nombre del estudiante: Bob | ||
- | Ingresa la calificación del estudiante (0-10): 7 | ||
- | Ingresa el nombre del estudiante: Andy | ||
- | Ingresa la calificación del estudiante (0-10): 3 | ||
- | Ingresa el nombre del estudiante: Bob | ||
- | Ingresa la calificación del estudiante (0-10): 2 | ||
- | Ingresa el nombre del estudiante: Andy | ||
- | Ingresa la calificación del estudiante (0-10): 10 | ||
- | Ingresa el nombre del estudiante: Andy | ||
- | Ingresa la calificación del estudiante (0-10): 3 | ||
- | Ingresa el nombre del estudiante: Bob | ||
- | Ingresa la calificación del estudiante (0-10): 9 | ||
- | Ingresa el nombre del estudiante: | ||
- | Andy : 5.333333333333333 | ||
- | Bob : 6.0 | ||
- | </ | ||
- | |||
- | == Puntos Clave: Tuplas | ||
- | 1. Las Tuplas son colecciones de datos ordenadas e inmutables. Se puede pensar en ellas como listas inmutables. Se definen con paréntesis: | ||
- | <code python> | ||
- | my_tuple = (1, 2, True, "una cadena", | ||
- | print(my_tuple) | ||
- | |||
- | my_list = [1, 2, True, "una cadena", | ||
- | print(my_list) | ||
- | </ | ||
- | |||
- | Cada elemento de la tupla puede ser de un tipo de dato diferente (por ejemplo, enteros, cadenas, boleanos, etc.). Las tuplas pueden contener otras tuplas o listas (y viceversa). | ||
- | |||
- | 2. Se puede crear una tupla vacía de la siguiente manera: | ||
- | <code python> | ||
- | empty_tuple = () | ||
- | print(type(empty_tuple)) | ||
- | </ | ||
- | |||
- | 3. La tupla de un solo elemento se define de la siguiente manera: | ||
- | <code python> | ||
- | one_elem_tuple_1 = (" | ||
- | one_elem_tuple_2 = " | ||
- | </ | ||
- | |||
- | Si se elimina la coma, Python creará una variable no una tupla: | ||
- | <code python> | ||
- | my_tuple_1 = 1, | ||
- | print(type(my_tuple_1)) | ||
- | |||
- | my_tuple_2 = 1 # Esto no es una tupla. | ||
- | print(type(my_tuple_2)) | ||
- | </ | ||
- | |||
- | 4. Se pueden acceder los elementos de la tupla al indexarlos: | ||
- | <code python> | ||
- | my_tuple = (1, 2.0, " | ||
- | print(my_tuple[3]) | ||
- | </ | ||
- | |||
- | 5. Las tuplas son immutable, lo que significa que no se puede agregar, modificar, cambiar o quitar elementos. El siguiente fragmento de código provocará una excepción: | ||
- | <code python> | ||
- | my_tuple = (1, 2.0, " | ||
- | my_tuple[2] = " | ||
- | </ | ||
- | |||
- | Sin embargo, se puede eliminar la tupla completa: | ||
- | <code python> | ||
- | my_tuple = 1, 2, 3, | ||
- | del my_tuple | ||
- | print(my_tuple) | ||
- | </ | ||
- | |||
- | 6. Puedes iterar a través de los elementos de una tupla con un bucle (Ejemplo 1), verificar si un elemento o no esta presente en la tupla (Ejemplo 2), emplear la función len() para verificar cuantos elementos existen en la tupla (Ejemplo 3), o incluso unir o multiplicar tuplas (Ejemplo 4): | ||
- | |||
- | <code python> | ||
- | # Ejemplo 1 | ||
- | tuple_1 = (1, 2, 3) | ||
- | for elem in tuple_1: | ||
- | print(elem) | ||
- | |||
- | # Ejemplo 2 | ||
- | tuple_2 = (1, 2, 3, 4) | ||
- | print(5 in tuple_2) | ||
- | print(5 not in tuple_2) | ||
- | |||
- | # Ejemplo 3 | ||
- | tuple_3 = (1, 2, 3, 5) | ||
- | print(len(tuple_3)) | ||
- | |||
- | # Ejemplo 4 | ||
- | tuple_4 = tuple_1 + tuple_2 | ||
- | tuple_5 = tuple_3 * 2 | ||
- | |||
- | print(tuple_4) | ||
- | print(tuple_5) | ||
- | </ | ||
- | |||
- | === EXTRA | ||
- | |||
- | También se puede crear una tupla utilizando la función integrada de Python **tuple()**. Esto es particularmente útil cuando se desea convertir un iterable (por ejemplo, una lista, rango, cadena, etcétera) en una tupla: | ||
- | <code python> | ||
- | my_tuple = tuple((1, 2, " | ||
- | print(my_tuple) | ||
- | |||
- | my_list = [2, 4, 6] | ||
- | print(my_list) | ||
- | print(type(my_list)) | ||
- | tup = tuple(my_list) | ||
- | print(tup) | ||
- | print(type(tup)) | ||
- | </ | ||
- | |||
- | De la misma manera, cuando se desea convertir un iterable en una lista, se puede emplear la función integrada de Python denominada **list()**: | ||
- | <code python> | ||
- | tup = 1, 2, 3, | ||
- | my_list = list(tup) | ||
- | print(type(my_list)) | ||
- | </ | ||
- | === Puntos Clave: Diccionarios | ||
- | 1. Los diccionarios son *colecciones indexadas de datos, mutables y desordenadas. (*En Python 3.6x los diccionarios están ordenados de manera predeterminada. | ||
- | |||
- | Cada diccionario es un par de clave : valor. Se puede crear empleado la siguiente sintaxis: | ||
- | <code python> | ||
- | my_dictionary = { | ||
- | key1: value1, | ||
- | key2: value2, | ||
- | key3: value3, | ||
- | } | ||
- | </ | ||
- | |||
- | 2. Si se desea acceder a un elemento del diccionario, | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | item_1 = pol_esp_dictionary[" | ||
- | print(item_1) | ||
- | |||
- | item_2 = pol_esp_dictionary.get(" | ||
- | print(item_2) | ||
- | </ | ||
- | |||
- | 3. Si se desea cambiar el valor asociado a una clave específica, | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | pol_esp_dictionary[" | ||
- | item = pol_esp_dictionary[" | ||
- | print(item) | ||
- | </ | ||
- | |||
- | 4. Para agregar o eliminar una clave (junto con su valor asociado), emplea la siguiente sintaxis: | ||
- | <code python> | ||
- | phonebook = {} # un diccionario vacío | ||
- | |||
- | phonebook[" | ||
- | print(phonebook) | ||
- | |||
- | del phonebook[" | ||
- | print(phonebook) | ||
- | </ | ||
- | |||
- | Además, se puede insertar un elemento a un diccionario utilizando el método '' | ||
- | <code python> | ||
- | pol_esp_dictionary = {" | ||
- | |||
- | pol_esp_dictionary.update({" | ||
- | print(pol_esp_dictionary) | ||
- | |||
- | pol_esp_dictionary.popitem() | ||
- | print(pol_esp_dictionary) | ||
- | </ | ||
- | |||
- | 5. Se puede emplear el bucle '' | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | for item in pol_esp_dictionary: | ||
- | print(item) | ||
- | |||
- | # salida: zamek | ||
- | # woda | ||
- | # gleba | ||
- | </ | ||
- | 6. Si deseas examinar los elementos (claves y valores) del diccionario, | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | for key, value in pol_esp_dictionary.items(): | ||
- | print(" | ||
- | </ | ||
- | |||
- | 7. Para comprobar si una clave existe en un diccionario, | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | if " | ||
- | print(" | ||
- | else: | ||
- | print(" | ||
- | </ | ||
- | |||
- | 8. Se puede emplear la palabra reservada '' | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | print(len(pol_esp_dictionary)) | ||
- | del pol_esp_dictionary[" | ||
- | print(len(pol_esp_dictionary)) | ||
- | |||
- | pol_esp_dictionary.clear() | ||
- | print(len(pol_esp_dictionary)) | ||
- | |||
- | del pol_esp_dictionary | ||
- | </ | ||
- | |||
- | 9. Para copiar un diccionario, | ||
- | <code python> | ||
- | pol_esp_dictionary = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | copy_dictionary = pol_esp_dictionary.copy() | ||
- | </ | ||
- | |||
- | == Excepciones | ||
- | El lidiar con errores de programación tiene (al menos) dos partes. La primera es cuando te metes en problemas porque tu código, aparentemente correcto, se alimenta con datos incorrectos. Por ejemplo, esperas que se ingrese al código un valor entero, pero tu usuario descuidado ingresa algunas letras al azar. | ||
- | |||
- | Puede suceder que tu código termine en ese momento y el usuario se quede solo con un mensaje de error conciso y a la vez ambiguo en la pantalla. El usuario estará insatisfecho y tu también deberías estarlo. Te mostraremos cómo proteger tu código de este tipo de fallas y cómo no provocar la ira del usuario. | ||
- | |||
- | La segunda parte de lidiar con errores de programación se revela cuando ocurre un comportamiento no deseado del programa debido a errores que se cometieron cuando se estaba escribiendo el código. Este tipo de error se denomina comúnmente " | ||
- | |||
- | Esta idea no es tan descabellada como puede parecer: incidentes de este tipo eran comunes en tiempos en que las computadoras ocupaban grandes pasillos, consumían kilovatios de electricidad y producían enormes cantidades de calor. Afortunadamente, | ||
- | |||
- | === Cuando los datos no son lo que deberían ser | ||
- | Escribamos un fragmento de código extremadamente trivial: leerá un número natural (un entero no negativo) e imprimirá su recíproco. De esta forma, 2 se convertirá en 0.5 (1/2) y 4 en 0.25 (1/4). | ||
- | |||
- | <code python> | ||
- | value = int(input(' | ||
- | print(' | ||
- | </ | ||
- | |||
- | ¿Hay algo que pueda salir mal? El código es tan breve y compacto que no parece que vayamos a encontrar ningún problema allí. | ||
- | |||
- | Parece que ya sabes hacia dónde vamos. Sí, tienes razón: ingresar datos que no sean un número entero (que también incluye ingresar nada) arruinará completamente la ejecución del programa. Esto es lo que verá el usuario del código: | ||
- | <code python> | ||
- | Traceback (most recent call last): | ||
- | File " | ||
- | value = int(input(' | ||
- | ValueError: invalid literal for int() with base 10: '' | ||
- | </ | ||
- | |||
- | Todas las líneas que muestra Python son significativas e importantes, | ||
- | |||
- | |||
- | ¿Cómo lo afrontas? ¿Cómo proteges tu código de la terminación abrupta, al usuario de la decepción y a ti mismo de la insatisfacción del usuario? | ||
- | |||
- | La primera idea que se te puede ocurrir es verificar si los datos proporcionados por el usuario son válidos y negarte a cooperar si los datos son incorrectos. En este caso, la verificación puede basarse en el hecho de que esperamos que la cadena de entrada contenga solo dígitos. | ||
- | |||
- | Ya deberías poder implementar esta verificación y escribirla tu mismo, ¿no es así? También es posible comprobar si la variable value es de tipo int (Python tiene un medio especial para este tipo de comprobaciones: | ||
- | <code python> | ||
- | type(value) is int | ||
- | </ | ||
- | |||
- | Su resultado es verdadero si el valor actual de la variable value es del tipo int. | ||
- | |||
- | Perdónanos si no dedicamos más tiempo a esto ahora; encontrarás explicaciones más detalladas sobre el operador '' | ||
- | |||
- | Es posible que te sorprendas al saber que no queremos que realices ninguna validación preliminar de datos. ¿Por qué? Porque esta no es la forma que Python recomienda. | ||
- | |||
- | === El Código Python | ||
- | En el mundo de Python, hay una regla que dice: "Es mejor pedir perdón que pedir permiso" | ||
- | |||
- | Detengámonos aquí por un momento. No nos malinterpretes, | ||
- | |||
- | En realidad, la regla dice: "es mejor manejar un error cuando ocurre que tratar de evitarlo" | ||
- | |||
- | "De acuerdo", | ||
- | |||
- | <code python> | ||
- | try: | ||
- | # Es un lugar donde | ||
- | # tu puedes hacer algo | ||
- | # sin pedir permiso. | ||
- | except: | ||
- | # Es un espacio dedicado | ||
- | # exclusivamente para pedir perdón. | ||
- | </ | ||
- | |||
- | Puedes ver dos bloques aquí: | ||
- | |||
- | * El primero, comienza con la palabra clave reservada '' | ||
- | * El segundo, la parte del código que comienza con la palabra clave reservada '' | ||
- | |||
- | Entonces, podríamos decir que estos dos bloques funcionan así: | ||
- | |||
- | * La palabra clave reservada '' | ||
- | * La palabra clave reservada '' | ||
- | * | ||
- | Como puedes ver, este enfoque acepta errores (los trata como una parte normal de la vida del programa) en lugar de intensificar los esfuerzos para evitarlos por completo. | ||
- | |||
- | === La excepción confirma la regla | ||
- | Reescribamos el código para adoptar el enfoque de Python para la vida. | ||
- | |||
- | <code python> | ||
- | try: | ||
- | value = input(' | ||
- | print(' | ||
- | except: | ||
- | print(' | ||
- | </ | ||
- | |||
- | Resumamos lo que hemos hablado: | ||
- | |||
- | * Cualquier fragmento de código colocado entre '' | ||
- | * El código en el bloque '' | ||
- | * Cuando el bloque '' | ||
- | |||
- | Ahora queremos hacerte una pregunta: ¿Es '' | ||
- | |||
- | === Cómo lidiar con más de una excepción | ||
- | La respuesta obvia es " | ||
- | |||
- | Sí, tienes razón: la división colocada dentro de la invocación de la función **print()** generará la excepción **ZeroDivisionError**. Como es de esperarse, el comportamiento del código será el mismo que en el caso anterior: el usuario verá el mensaje "No se que hacer con...", | ||
- | |||
- | ¿Es posible? Por supuesto que lo es. Hay al menos dos enfoques que puedes implementar aquí. | ||
- | |||
- | El primero de ellos es simple y complicado al mismo tiempo: puedes agregar dos bloques '' | ||
- | |||
- | Esta solución es buena, pero es un poco larga: el código se hincha innecesariamente. Además, no es el único peligro que te espera. Toma en cuenta que dejar el primer bloque '' | ||
- | |||
- | === Dos excepciones después de un try. | ||
- | <code python> | ||
- | try: | ||
- | value = input(' | ||
- | print(' | ||
- | except ValueError: | ||
- | print(' | ||
- | except ZeroDivisionError: | ||
- | print(' | ||
- | </ | ||
- | |||
- | Como puedes ver, acabamos de agregar un segundo '' | ||
- | |||
- | Pero esta todavía no es la última palabra de Python sobre excepciones. |