Saltar la navegación

3.3. Archiva el contenido

Rétor dice:Hasta este momento, nos hemos movido por la programación conociendo estructuras de control y de datos que se ejecutan en pantalla. Has escrito el código que has desarrollado en ficheros, y al ejecutarlos nos han pedido datos por teclado y mostrado información en pantalla. Pero hay veces en las que los programas necesitan guardar información de manera permanente, o leerla desde algún archivo que se encuentra en el sistema informático. ¡Necesitamos acceder a ficheros desde nuestros programas! Todo está previsto: Python dispone de órdenes para ello que vas a conocer a continuación en este apartado.

1. Memoria de LOG

Chico obtiene errorMientras usas alguna aplicación ya sea en el ordenador o en tu dispositivo móvil, seguramente alguna vez habrás sufrido un fallo: se ha quedado "colgado" el programa o se ha cerrado de repente generando un error.
Para repararlo o recuperar datos, quizás hayáis tenido que acceder o dar información al centro de soporte informático de los ficheros log.

Abrid el fichero log que se adjunta y responded a las siguientes cuestiones, consensuando las aportaciones de todos los miembros del grupo: fichero.

  • Si tuviérais que elaborar una tabla para escribir por filas las líneas de fichero separando cada elemento de la línea en su correspondiente columna, ¿qué información pondríais en los encabezados de las columnas?
  • ¿Cómo pensáis que se genera el fichero log?¿Quién lo escribe?
  • Utilizando la imaginación: ¿cómo creéis que ha debido tener esto en cuenta el programador de la aplicación?

Grabación secuencial en un archivo o en una base de datos de todos los acontecimientos (eventos o acciones) que afectan a un proceso particular (aplicación, actividad de una red informática, etc.). De esta forma constituye una evidencia del comportamiento del sistema.

Explicación de un LOG

Si necesitáis ayuda o queréis consultar otro formato de ejemplo de un fichero log y su análisis, podéis consultar información sobre estos ficheros log en el siguiente enlace.

2. ¿Preparado para salvar la información?

En ocasiones, los programas que creemos necesitarán guardar datos de manera permanente o dar resultados sobre los que será necesario trabajar posteriormente y no solo obtener los datos por pantalla. Para no perder la información que maneja o que genera un programa, desde Pyhton podemos utilizar los ficheros.

Para trabajar con ficheros deberás seguir siempre tres pasos: 1ºABRIR FICHERO - 2ºLEER O ESCRIBIR FICHERO - 3ºCERRAR FICHERO. Sitúa cada comando debajo de la acción que realiza y ¡descubre qué comandos puedes utilizar para cada una de estas fases! Puedes intentarlo tantas veces como necesites.

¿Modo w, r, a ó x?

Seguramente te preguntarás por qué existen varios modos de expresar el comando open. Si no conoces las diferencias entre uno y otro, aquí puedes comprobarlas:

Modo "w"

Abrir el fichero para escribir. Crea el fichero si no existe y borra el contenido anterior del fichero si existía.

Modo "x"

Opción solo para abrir el fichero a la vez que se crea. Si ya existía el fichero, se obtiene un error al usar este modo.

Modo "a"

Abrir el fichero para añadir contenido al final. Si no existe, lo crea.

Modo "r"

Abre el fichero solo para leer. Siempre empieza a leer desde el principio y, si no existe, da un error.

3. Maneras de leer...perfeccionando la técnica

Cuando abrimos un fichero para su lectura línea a línea, con lo que ya conoces, quizás pienses que podríamos usar un bucle. Pero nos encontramos un problema: ¿Cuántas líneas tiene el fichero?¿Hasta cuándo sigo leyendo? ¡Pero hay solución!: Una estructura en Python nos soluciona este aspecto:

fichero = open("Tickets.txt","r")
for lineas in fichero:
#Aquí los comandos a ejecutar
#por cada línea
f.close()

Este bucle for es equivalente a realizar la asignación linea=f.readline() en cada vuelta.

Ahora que ya sabemos recorrer las líneas de un fichero, vamos a abrir el fichero que contiene el ticket para la reserva de asientos generado por nuestro programa y lo leeremos para imprimirlo/mostrarlo por pantalla al usuario:
Ticket generado por programa.

Función print()

Si leemos línea por línea e imprimimos, nos encontramos con que la orden print estará añadiendo un salto de línea adicional al que se encuentra en la propia línea que leemos del fichero. Para evitarlo, utilizaremos la opción end="" que, pasada como argumento a la función print() elimina el salto de línea de dicha función:

f = open ("TICKETS.txt","r")
for linea in f:
print (linea, end="")
f.close()
Resultado de imprimir el ticket.

Función rstrip()

Otro ejemplo para imprimir el contenido de cada línea leída es el uso de la función de cadena de caracteres rstrip(): Esta función elimina los espacios en blanco al final de la cadena que llama a la función. Mira su uso en el ejemplo:

f = open ("TICKETS.txt","r")
for linea in f:
print (linea.rstrip())
f.close()

El resultado obtenido con este código es el mismo que en el caso anterior. Pruébalo con tu IDLE de Python.

Lectura completa

Finalmente, aquí tenes la última opción: la lectura del fichero completo de una sola vez. Esto es posible gracias a que la función que realiza la lectura genera una lista de tantos elementos como líneas tiene el fichero. La función que realiza esto es readlines(). ¡Comprueba el ejemplo!:

f = open ("TICKETS.txt","r")
total = f.readlines()
for linea in total:
print (linea.rstrip())
f.close()

Si deseas ver el valor de la variable tipo lista que se crea, prueba a imprimir su valor con print total

4. Ayuda a tus usuarios con los errores en ficheros

Imagen try-exceptEn el recurso anterior aprendimos cómo utilizar las excepciones (bloque try-except) para informar de los posibles errores que pueden obtenerse al utilizar un programa y evitar que se rompa su funcionamiento, proporcionando información al usuario de lo sucedido. Ahora lo aplicarás a los posibles errores que puedes encontrar en el trabajo con ficheros:. Sigue los pasos que te indica el ejercicio y completa el programa para salvar los errores que se producen:

fich_ent = open("numeros_enteros.txt", "r")
# Línea "artificial" para generar un error de índice en
#nuestro ejemplo.
# Cambiando 9 por 10 el programa no genera error.
num_valores = 9
lista_enteros = [0]*num_valores
for i, linea in enumerate(fich_ent): # Uso de enumerate()
lista_enteros[i] = int(linea)
print(lista_enteros)
fich_ent.close()
  1. Ejecuta este programa que tienes en la columna izquierda. ¿Qué error se produce?¿A qué se debe?
  2. Guarda en tu directorio de trabajo Python el siguiente archivo: numeros_enteros.txt A continuación, vuelve a ejecutar el código. ¿Qué error lanza ahora la ejecución del programa?¿Cuál es ahora la causa?

Vamos a intentar que nuestro programa esté protegido contra los dos errores anteriores y al funcionar pueda indicar a qué se han debido los errores:

  • Cuando el sistema no encuentra el fichero que pretende abrir se lanza una excepción de nombre FileNotFoundError.
  • Cuando se calcula mal el número de líneas que se van a leer de un fichero se lanza una excepción de nombre IndexError.

Continuando entonces con el ejercicio, ahora:

  1.  Programa un bloque try-except que contenga dos órdenes except para evitar cada una de estas dos excepciones lanzadas anteriormente, mostrando por pantalla los mensajes: "Error, el fichero que se intenta leer no existe" y "Error, el fichero contiene más líneas de las programadas", en cada error correspondiente.
  2. Cambia el bloque de operaciones pertenecientes al try para que el número de valores a leer se pida por teclado al usuario.
  3. Añade a continuación del último except la siguiente orden (que también pasaría a formar parte del bloque try-except) y elimina del bloque try la llamada a la función print:
    else:
        print ("El contenido del fichero es:")
        print(lista_enteros)
    ¿Qué sucede ahora cuando se introduce por teclado el número 10?¿Cuándo se ejecuta este nuevo bloque?¿Para qué sirve?
  4. Finalmente, añade como parte también del bloque del tratamiento de errores, y a continuación del else, el comando:
    finally:
        print("Análisis del fichero terminado.")
    Haz varias pruebas de funcionamiento provocando también errores, ¿en qué casos se ejecuta ahora esta nueva orden?¿Qué puede indicar al usuario?
  5. Escribe en tu blog de la asignatura lo que has trabajado sobre el manejo de estos dos nuevos errores ylas respuestas a las preguntas sobre estas os nuevas órdenes aprendidas.

¿Necesitas ayuda con el código?

A continuación puedes comprobar si tu código se parece al siguiente, que arregla los fallos del programa:

try:
fich_ent = open("numeros_enteros.txt", "r")
# Línea "artificial" para generar un error de índice en nuestro ejemplo
# Cambiando 9 por 10 el programa no genera error
num_valores = int(input ("Introduzca el número de líneas a leer.\n"))
lista_enteros = [0]*num_valores
for i, linea in enumerate(fich_ent): # Nótese el uso de enumerate()
lista_enteros[i] = int(linea)
fich_ent.close()
except FileNotFoundError:
print ("Error, el fichero que se intenta leer no existe.")
except IndexError:
print ("Error, el fichero contiene más líneas de las programadas.")
except:
print ("Error desconocido.")
else:
print ("El contenido del fichero es:")
print(lista_enteros)
finally:
print("Análisis del fichero terminado.")