1 00:00:00,560 --> 00:00:10,699 Bueno, ahora vamos a continuar con las excepciones. Las excepciones las vamos a ver de una forma, o las voy a intentar explicar de una forma que sea muy sencilla para que entendamos el concepto. 2 00:00:10,759 --> 00:00:19,440 Esto ya lo vimos en C. Básicamente es una forma de controlar posibles errores normalmente que se producen durante el proceso de ejecución, 3 00:00:19,440 --> 00:00:27,920 porque un dato esté mal introducido, un fichero que se haya leído no esté bien hecho o tenga algún error, algo de ese estilo. 4 00:00:27,920 --> 00:00:32,079 ¿Vale? Es decir, que no son errores de que hayamos escrito algo mal en el programa. 5 00:00:35,119 --> 00:00:40,719 Vale. Bueno, ahí os he puesto un ejemplo de cómo manejábamos estos errores en C. 6 00:00:40,859 --> 00:00:46,679 No quiero entretenerme con esto mucho porque básicamente esto ya lo vimos en la primera evaluación. 7 00:00:47,880 --> 00:00:54,079 Bueno, era un codiguito que hacía una lectura y en función de si la lectura que se había leído por el scanf era buena o no, 8 00:00:54,219 --> 00:00:57,880 pues daba un error o no daba error. ¿Vale? Y algo parecido con la lectura de fichero. 9 00:00:57,880 --> 00:01:26,879 Bien, si esto no lo llevamos a Python, que es lo que aquí al final ahora nos interesa, ¿vale? Fijaros, nosotros ahora lo que vamos a tener es básicamente una nueva estructura que se llama try y except, ¿vale? 10 00:01:26,879 --> 00:01:32,879 a un flotante esto lo hemos dicho en clase puede producir errores porque puede producir 11 00:01:32,879 --> 00:01:36,659 errores porque imaginaros que yo en vez de haber escrito un número escrito una palabra escrito 12 00:01:36,659 --> 00:01:42,420 casa pues casa va a dar un error vale entonces lo que nosotros vamos a hacer es que el programa sea 13 00:01:42,420 --> 00:01:49,659 capaz de ejecutarse y seguir funcionando normalmente pero que nos notifique de alguna 14 00:01:49,659 --> 00:01:57,420 forma o que él sepa que un error entonces lo que nosotros haremos será que digamos para que 15 00:01:57,420 --> 00:02:04,760 entendamos intenta convertir en la cadena flotante vale y si no puede vale en el caso de que no pueda 16 00:02:04,760 --> 00:02:09,740 devuelve un error y ese error va a ser un texto por pantalla que voy a decir esto no es un número 17 00:02:09,740 --> 00:02:15,520 vale y luego el número que va a devolver la función en vez de ser un valor vale por ejemplo 18 00:02:15,520 --> 00:02:19,139 Si hubiera pasado el 4,5, el 4,8, pues va a ser nada, ¿vale? 19 00:02:19,139 --> 00:02:20,759 Un fichero vacío, nulo, ¿vale? 20 00:02:21,460 --> 00:02:24,860 Y esto nos lo podemos llevar exactamente igual a la lectura de ficheros, ¿vale? 21 00:02:24,900 --> 00:02:26,199 Que lo veremos ahora más adelante. 22 00:02:26,879 --> 00:02:30,500 Intenta abrir un fichero en modo escritura, ¿vale? 23 00:02:31,000 --> 00:02:32,699 Lee su contenido y luego ciérralo. 24 00:02:33,060 --> 00:02:35,800 Y ahora, puedes encontrarte varios errores. 25 00:02:35,939 --> 00:02:38,419 El primer error que te puedes encontrar es que el fichero no te ha encontrado, ¿vale? 26 00:02:38,460 --> 00:02:39,759 Pues que ese fichero no exista. 27 00:02:40,199 --> 00:02:42,879 Por ejemplo, el fichero datos.txt no exista, ¿vale? 28 00:02:42,879 --> 00:02:57,180 Y el otro error puede ser que no tenga permisos, ¿vale? Pues que sea un fichero que no tenga permisos de lectura, pues eso también puede producir errores, ¿vale? Pero el programa este detectaría el error y seguiría funcionando tan tranquilo, ¿vale? 29 00:02:57,180 --> 00:03:16,180 ¿Vale? Había puesto un ejemplo de una estructura completa que tiene varios elementos, ¿vale? Tiene varios except, ¿vale? Como veis aquí hay dos, ¿vale? Y luego tiene también otra cosa que podemos implementar que es un else, ¿vale? Que solo se va a ejecutar si no hubo ninguna de las excepciones, ¿vale? Las excepciones que nosotros hemos puesto, ¿cuáles son? 30 00:03:16,180 --> 00:03:36,240 Pues fijaros, si lo que estamos haciendo es el mismo programa, un programa que convierte a entero, ¿vale? Pues lo primero que hace, si ese entero es mayor que 0, ¿vale? Si lo consigue convertir, ¿vale? Porque RSSI tiene que ser 0, tiene que ser mayor que 0, perdón, ¿vale? Perdón, el RSSI siempre tiene que ser negativo, ¿vale? 31 00:03:36,240 --> 00:03:50,759 Entonces, si no es negativo, es decir, cuando lo convierte y sale a positivo, la conversión no va a dar un error, porque un número positivo está bien convertido en entero, pero si diera positivo nosotros tenemos que forzar en cierta forma ese error para que el programa no funcione. 32 00:03:50,759 --> 00:04:11,780 Entonces lo que haremos será raise, como eleva, ¿vale? Un error de valor. Y aparte imprimimos un texto que es rssi, debe ser negativo. Y ahora, de ahí entraríamos en este step, ¿vale? Es decir, como se ha producido un error de valor, pues notificamos el error de valor, ¿vale? Y devuelve nada. 33 00:04:11,780 --> 00:04:24,300 Y ahora, si hay un tipo de error, es decir, y esto ya sería porque en vez de haber pasado un entero, hayamos pasado una palabra, una letra, lo que sea, ¿vale? Pues sí que pondría tipo de dato incorrecto, ¿vale? 34 00:04:24,300 --> 00:04:35,240 Y si ninguna de estas dos excepciones salta, pues imprímeles y dice RSSI válido, imprime su valor, ¿vale? 35 00:04:35,540 --> 00:04:41,459 Devuelve ese RSSI, eso es lo que va a devolver la función procesar medición, ¿vale? 36 00:04:42,019 --> 00:04:47,019 Y luego tenemos el finally, que el finally siempre que esté puesto siempre se va a ejecutar. 37 00:04:47,060 --> 00:04:51,319 Se va a ejecutar, perdón, hay un error o no. 38 00:04:51,319 --> 00:05:05,060 Entonces, ¿qué va a ejecutar aquí? Pues print proceso completado, ¿vale? Es decir, es una forma de tener un mensaje de log o un mensaje de traza que nos indica que el programa está funcionando bien, ¿vale? 39 00:05:05,300 --> 00:05:20,040 Entonces, para que lo entendamos con un diagrama de flujo, básicamente lo que haríamos sería un try, ¿vale? Vamos a intentar hacer algo, convertir un fichero, convertir un dato, leer un fichero, lo que sea y ahora comprobamos si hay error, que si lo hay, generamos una excepción, ¿vale? 40 00:05:20,040 --> 00:05:33,439 Y si generamos una excepción, siempre ejecutaremos el finally. Y ahora, que no hay ningún error, pues nos vamos al else, ¿vale? Y generamos y volvemos otra vez al else, vamos al finally, ¿vale? Lo que digo, el finally siempre se ejecuta, ¿vale? 41 00:05:33,439 --> 00:05:50,060 Y esto que decía antes, raise, ¿vale? Pues es una forma de nosotros lanzar una excepción manualmente. En este código anterior, ¿vale? La conversión entera no daba ningún error, simplemente convertía un número positivo. 42 00:05:50,060 --> 00:05:58,019 Pues nosotros para forzar ese error lo que hacíamos era raiseValueError, ¿vale? Forzar ese error porque sabemos que ese valor no puede ser positivo. 43 00:05:59,620 --> 00:06:07,300 Y aquí he puesto tipos de excepciones más frecuentes, ¿vale? ValueError, que es pues una conversión de tipo inválida, ¿vale? 44 00:06:08,500 --> 00:06:14,819 KeyError, es decir, que sea un... estamos hablando de diccionarios que ya lo hemos visto antes y que ese clave no exista, ¿vale? 45 00:06:15,459 --> 00:06:19,040 Un índice de error, porque estamos incidiendo en una lista que no tenga ese valor. 46 00:06:19,620 --> 00:06:22,360 Un fichero no existido, que el fichero no tenga permisos. 47 00:06:22,759 --> 00:06:25,139 Una división entre ceros, ¿vale? Que tampoco se puede. 48 00:06:26,319 --> 00:06:30,300 Tipos incompatibles de datos, es decir, sumar texto y número, ¿vale? 49 00:06:30,360 --> 00:06:32,500 Eso no tiene sentido, da error, ¿vale? 50 00:06:32,500 --> 00:06:34,800 Y luego, errores del sistema operativo, ¿vale? 51 00:06:39,379 --> 00:06:46,819 Y aquí os he puesto un ejemplo de un programa típico que podríamos hacer en un sistema de telecomunicaciones, ¿vale? 52 00:06:46,819 --> 00:06:57,040 Que es leer un valor donde ponemos un prompt, es decir, una petición, pues quiero leer el RSSI o quiero leer, aquí he puesto como ejemplo de ejecución el RSSI, ¿vale? 53 00:06:57,199 --> 00:07:03,220 Y le digo, el tipo, por defecto quiero que sea flotante, pero yo aquí en vez de haberle puesto float podría ponerle int, ¿vale? 54 00:07:03,259 --> 00:07:04,480 Porque sí quiero que sea entero. 55 00:07:05,100 --> 00:07:07,139 ¿Cuál es su valor mínimo y su valor máximo, vale? 56 00:07:07,339 --> 00:07:11,600 Y entonces estáis leyendo, hace su try y hace su except, ¿vale? 57 00:07:11,600 --> 00:07:13,839 En caso de que el valor sea malo. 58 00:07:13,839 --> 00:07:25,100 Y aquí veis que forzamos, si yo le he puesto que el valor tenga un valor, que deba de tener un valor mínimo y deba de tener un valor máximo, ¿vale? Pues forzamos esos errores con ese raise, ¿vale? 59 00:07:27,459 --> 00:07:31,079 Si analizáis un poco lo que hemos visto antes podréis entenderlo mejor. 60 00:07:33,319 --> 00:07:42,720 Y continuamos con ficheros, ¿vale? Ficheros, en C os dejé los apuntes para que los vierais, pero no trabajamos sobre ellos. 61 00:07:42,720 --> 00:07:46,779 En el caso de Python sí vamos a trabajar porque es súper sencillo y muy fácil, ¿vale? 62 00:07:47,560 --> 00:07:52,040 Entonces, aquí he puesto la comparativa para que veáis las diferencias, pero nos vamos a centrar aquí. 63 00:07:52,339 --> 00:07:54,879 Y he puesto tres formas de abrir ficheros, ¿vale? 64 00:07:54,920 --> 00:07:57,540 Que lo vamos a hacer siempre con with open, ¿vale? 65 00:07:57,699 --> 00:08:02,939 Y eso es cómodo porque al poner with gestiona directamente que el fichero se cierre. 66 00:08:03,000 --> 00:08:06,319 No tenemos nosotros que hacer como hacíamos aquí en C, ¿vale? 67 00:08:06,500 --> 00:08:09,699 O como si no pusiéramos en Python with también lo tendríamos que hacer. 68 00:08:10,019 --> 00:08:12,199 Estar pendientes de cerrar ese fichero, ¿vale? 69 00:08:12,199 --> 00:08:34,840 Entonces, tenemos tres opciones. Ir leyendo línea a línea, que sería esta opción, ¿vale? Abrimos un fichero en los .txt en modo lectura y ahora a ese fichero lo vamos a llamar f y ahora vamos leyendo línea a línea en f, ¿vale? Hasta que detectemos el final de línea, ¿vale? 70 00:08:34,840 --> 00:09:00,519 Luego también podemos leer todo el fichero a la vez, poniendo f.read, ¿vale? Leeríamos todo el fichero y entonces en contenido se guardaría todo el fichero. Otra opción. Y luego podemos ir leyendo línea a línea y lo vamos guardando como una lista, ¿vale? Pues entonces líneas de cero tendríamos la primera línea, líneas de una segunda línea, bueno, esto dependiendo del programa habrá una forma que nos interese más u otra. 71 00:09:00,519 --> 00:09:17,169 Ahora, ejemplo de escritura, ¿vale? Aquí hay varios modos de abrir ficheros, esto no tiene que ver únicamente con escritura, es modo de abrir ficheros, que lo hemos visto también aquí, ¿vale? Aquí os he enseñado cómo abríamos con R, ¿vale? R que es el modo lectura, que es el modo por defecto. 72 00:09:17,169 --> 00:09:21,149 Luego tenemos el modo de escritura, que borra si el archivo ya existe, ¿vale? 73 00:09:21,889 --> 00:09:28,149 Y luego tenemos el modo de append, de añadir al final, es decir, si el fichero ya existe es recomendable utilizar a, ¿vale? 74 00:09:28,649 --> 00:09:32,889 Luego tenemos lectura y escritura, crear un fichero, lectura binaria y escritura binaria, ¿vale? 75 00:09:33,509 --> 00:09:36,450 Y bueno, aquí os pongo un ejemplo de escribir un log de red, ¿vale? 76 00:09:37,070 --> 00:09:45,789 Bueno, aquí tenemos una función, registrar evento, que lo que recibe es el nombre del fichero, el tipo del evento y por defecto el nivel. 77 00:09:45,789 --> 00:10:02,129 Yo he puesto por defecto info, ¿vale? Pero veis que cuando hago uso de aquí, en uno de ellos hago uso warning, en este no le pongo nada, por lo tanto pasa info y aquí paso error, ¿vale? Estos dos, ese warning serían los dos el nivel, ¿vale? Sustituiría en info. 78 00:10:02,129 --> 00:10:07,009 Bien, pues lo que hacemos es que en timestamp creo un tiempo, ¿vale? 79 00:10:07,230 --> 00:10:11,909 Utilizando esta función, pues guardo el año, el mes y el día, la hora, los minutos y los segundos 80 00:10:11,909 --> 00:10:18,490 Y luego me creo una cadena de texto que está formada por esa fecha, esa línea temporal 81 00:10:18,490 --> 00:10:23,029 El nivel, ¿vale? Que por defecto es info, a no ser que yo le pase algo 82 00:10:23,029 --> 00:10:26,769 Y luego el evento, ¿vale? En este caso el evento, pues ya veis que pone 83 00:10:26,769 --> 00:10:31,370 API desconectado, RSS y AP2, umbral superado en AP3, ¿vale? 84 00:10:31,370 --> 00:10:45,570 ¿Y qué hacemos? Abrimos el fichero en modo append, ¿vale? Y vamos escribiendo línea a línea. ¿Vale? Muy sencillito. Si hay varias líneas, pero puede ser que no. 85 00:10:45,570 --> 00:10:54,100 Aquí os he puesto un ejemplo sobre cómo leer un fichero CSV 86 00:10:54,100 --> 00:10:59,039 Aquí solo voy a entretenerme porque esto ya lo he explicado un poco 87 00:10:59,039 --> 00:11:01,980 Veis que hay una excepción, un try step 88 00:11:01,980 --> 00:11:07,700 Y me voy a centrar en esto que veis aquí, en esta línea 89 00:11:07,700 --> 00:11:09,639 Para que entendamos algunas funciones 90 00:11:09,639 --> 00:11:11,080 Campos, ¿qué hace? 91 00:11:11,080 --> 00:11:13,559 Vamos a leer una línea 92 00:11:13,559 --> 00:11:17,019 Utilizando cabecera igual, f redline 93 00:11:17,019 --> 00:11:30,000 Pues ahí leeremos la cabecera. ¿Y ahora qué hacemos con la cabecera? Pues en primer lugar, hacemos un split coma. ¿Qué hace el split coma? El split coma lo que va a hacer es dividirnos el fichero en donde haya una coma. 94 00:11:30,000 --> 00:11:45,779 Donde haya una coma, nos lo va a dividir. Entonces, nosotros vamos a tener, pues fijaros, aquí vamos a tener, vamos a separar por esa coma y va a separar por esa coma, ¿vale? Entonces, lo tendríamos ahí separado. 95 00:11:45,779 --> 00:11:47,899 y luego strip lo que hace es que elimina los espacios 96 00:11:47,899 --> 00:11:49,559 entonces todos los espacios que haya 97 00:11:49,559 --> 00:11:51,039 lo elimina, ¿vale? 98 00:11:51,519 --> 00:11:53,600 y es una forma pues de tener los campos 99 00:11:53,600 --> 00:11:54,919 más cómodos, ¿vale? 100 00:11:57,299 --> 00:11:59,340 y así luego, veis que aquí 101 00:11:59,340 --> 00:12:01,100 ¿vale? con esta función 102 00:12:01,100 --> 00:12:03,039 nos vamos generando 103 00:12:03,039 --> 00:12:04,820 en registro, ¿vale? 104 00:12:05,220 --> 00:12:07,460 vamos guardando un diccionario donde vamos guardando 105 00:12:07,460 --> 00:12:09,159 el campo, ¿vale? 106 00:12:09,320 --> 00:12:11,460 y el valor, que el valor lo leemos 107 00:12:11,460 --> 00:12:13,759 de una forma parecida, ¿vale? separamos por coma 108 00:12:13,759 --> 00:12:14,899 y luego quitamos los espacios 109 00:12:14,899 --> 00:12:17,120 ¿vale? es una forma pues 110 00:12:17,120 --> 00:12:42,039 A partir de un fichero CSV, que es como si fuera un... CSV viene de la sigla de Coma Separated Values, ¿vale? A partir de ahí es un fichero, es decir, valores separados por comas, es una forma de crearnos una lista con diferentes valores, ¿vale? 111 00:12:42,039 --> 00:13:03,710 Y aquí os pongo un ejemplo sobre cómo escribirlo. El proceso es parecido, ¿vale? Solo que ahora lo que vamos a hacer es unirlo. Fijaros, hacemos un join, los campos los unimos utilizando como elemento de unión las comas, ¿vale? Pero bueno, es que esto no tiene tampoco más historia. Es bastante estándar. 112 00:13:07,019 --> 00:13:11,039 Aquí pongo un ejemplo de lectura de un fichero de log, ¿vale? 113 00:13:11,580 --> 00:13:19,559 Veis aquí, esto es el fichero de log estándar, que tiene tres campos, línea de tiempo, punto de acceso y nivel de RSSI, ¿vale? 114 00:13:19,840 --> 00:13:20,980 Separados por la barra. 115 00:13:21,320 --> 00:13:23,779 Entonces, fijaros, hacemos algo parecido. 116 00:13:24,240 --> 00:13:32,740 Lo primero que hacemos es leer la línea y quitar los espacios, todos los espacios que haya. 117 00:13:32,740 --> 00:13:50,679 ¿Vale? Ahora, si la línea, si no hay ninguna línea, está vacía o si tiene un asterisco, asumimos que es una línea vacía o comentario. Por lo tanto, todo lo que haya después nos lo saltamos. Hacemos un continuo, nos saltamos todo y volvemos. ¿Vale? Entonces, de nuevo, cogemos la siguiente línea. 118 00:13:50,679 --> 00:14:00,980 Y ahora le quitamos los espacios, ¿vale? Y luego lo que hacemos es que las separamos por barras, es decir, donde hay una barra separamos. 119 00:14:01,320 --> 00:14:11,159 Y entonces vamos a tener un array, ¿vale? Donde partes, va a tener partes 0, partes 1 y partes 2, ¿vale? 120 00:14:11,159 --> 00:14:37,679 ¿Vale? Entonces, si el tamaño de partes es distinto que 3, ¿vale? Da un error o suma un error y ahora continúa, ¿vale? Continúa y hace un try. ¿Qué hace ese try? Pues va a crear un diccionario de diccionarios, ¿vale? Va a crear un ts, ¿vale? Lo que sería el timestamp, la marca de tiempo, un ap del punto de acceso y un nivel de rssi, ¿vale? 121 00:14:37,679 --> 00:14:43,480 Y lo mismo, lo vuelvo otra vez a quitar los espacios para asegurarse que si son números, pues que no haya ningún error, ¿vale? 122 00:14:43,980 --> 00:14:47,759 Y el resto, pues un poco estándar de cosas que ya hemos visto. 123 00:14:48,340 --> 00:14:53,399 Y este código, pues como veis, ¿vale? Cargaría cuatro eventos bien y un error, ¿vale? 124 00:14:53,539 --> 00:15:00,759 Cargaría un error porque este de aquí no tiene longitud 3, ¿vale? Entonces daría un error. 125 00:15:00,759 --> 00:15:12,669 Y finalmente os he dejado un proyecto, esto lo he dejado para que lo analicéis vosotros, para que tengáis un ejemplo de un analizado de red de Wi-Fi. 126 00:15:13,090 --> 00:15:15,429 Puede serviros para cualquier cosa. 127 00:15:16,669 --> 00:15:25,769 Y como siempre al final, una comparativa entre conceptos que hemos visto en C y las ventajas que nos permite hacerlo en Python como lenguaje de programación. 128 00:15:27,309 --> 00:15:30,809 Pues esto es todo de la unidad de trabajo 7.