Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Leer el último registro en archivo .txt en python
#1
Hola, ¿cómo están?
Ya casi no estoy fallando ningún domingo Big Grin , en este caso créame que lo intente de muchas maneras y no encuentro enmendar el error. -
Tengo un archivo de texto que contiene lo siguiente:
1  123
2  345
3  567
4  789
Tengo que establecer el próximo código que sí o si tiene que ser 5, no puedo contar las líneas porque 
el programa tiene la posibilidad de borrar una línea: 
1  123
2  345
4  789
Si cuento las lineas el código seria 3+1=4 y el 4 estaría repetido cosa que no puede ocurrir porque lo 
utilizo para la búsqueda. -
Lo que ocurre es que si tengo más de una línea el programa funciona correctamente, pero si tengo un
Solo registro me da error, tmp aparece vacío. -

Código:
Esta es la función:
    def establecer_codigo():
    archivo = abrir_lectura()
    tmp = archivo.readlines()[-1]
    tmp = tmp.split()
    codigo = int(tmp[0])
    archivo.close()

    return codigo
Un saludo.
Daniel
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#2
hola,
casi lo has pillado


Código:
with open('salida.txt', 'r') as f:
   lineas = f.read().splitlines()  # convertimos en una lista de lineas
   ultima_linea = lineas[-1]   # tomamos el ultimo elemento de la lasta de lineas
   ult_lin_cortada = ultima_linea.split()  # el formato de la linea es clave / espacio / dato
   ultima_clave = ult_lin_cortada[0]
   clave_a_insertar = int(ultima_clave) + 1
   print (clave_a_insertar)


La clave esta en la linea 2
Responder
#3
Me da el mismo error
[Imagen: orno7a.png]
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#4
daniel, la separación de clave-valor ¿es un espacio, un tabulador '\t', ...? ¿el fichero es accesible dentro de tu función establecer_codigo? ¿cual es el valor de la variable ult_linea_cortada, y que tipo de datos almacena "print(type(ult_linea_cortada))"?

el codigo que te puse funciona con los datos que has mostrado (he considerado el separador un espacio), y que puse en un fichero llamado salidas.txt:

1  123
2  345
4  789

edito:

Estoy observando los errores. ¿Como tienes abierto el fichero? porque veo que primero haces un "agregar", asi que supongo que lo tienes abierto para escritura "w". Para leerlo, primero tendras que cerrar el fichero y volver a abrirlo para lectura, etc... y viceversa.

tambien te puede pasar que tengas el puntero interno del fichero al final. Por ejemplo:

Código:
with open('salida.txt', 'r') as f:
   # el puntero interno del fichero está al principio
   lineas_A = f.read().splitlines()
   print(lineas_A)   # imprime la lista : ['1  123', '2  345', '4  789']
   # ahora el puntero está al final del fichero
   lineas_B = f.read().splitlines()
   print(lineas_B)   # ahora la lista es vacía : []
para poner el puntero al principio: fichero.seek(0, 0)
Un articulo sobre como mover el puntero interno aqui: https://www.tutorialspoint.com/python/file_seek.htm
Responder
#5
Con el código que dejo a continuación funciona a la perfección, con o, 1, 100 registros, lo único que debo refinar es esta línea:

Código:
contenido = fo.read(2)

 lo que pasa que si lo dejo de esta otra(me da el error) :
 
Código:
contenido = fo.read()

De esta manera, si imprimo el contenido de: tmp  ==> resultado = '\n'
Me dice que el índice esta fuera de rango.
Yo estoy seguro de que no puede fallar porque al grabar en el archivo lo hago comenzando en el extremo izquierdo y aunque lo que este grabado sea solo 1 1 leyendo 2 bits alcanza para que me informe si el archivo esta vacio o no, solo quedaría hacerlo de esta manera pero no sé cuál es el costo para el sistema operativo, digo por si el archivo contara con 500.000 registros. -  


Código:
fo = open("practicas.txt", "r")
contenido = fo.read()
fo.close()
fo = open("practicas.txt", "r")
.................

Código:
fo = open("practicas.txt", "r")
contenido = fo.read(2)

if contenido == '':
   codigo = 0
else:
   tmp = fo.readlines()[-1]
   tmp = tmp.split()
   codigo = int(tmp[0])

codigo += 1
print(codigo)
voy a seguir indagando, me interesa mucho lo que pusiste en el post anterior(seek),gracias por tu tiempo
Daniel
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#6
a ver ....
cuando dices :


Código:
contenido = fo.read(2)

le estas diciendo al fichero, que donde esté el puntero interno, lea a partir de ahí dos bytes (dos letras/caracteres). Imaginemos que el puntero está en f.seek(0,0); en nuestro ejemplo la primera linea es justo al inicio de '1  123'. Cuando haces esa instrucción le dices al fichero que tome los dos primeros bytes el '1 y un espacio'. Tu cuentas con que las claves de tu fichero no van a pasar nunca de 99 (dos bytes).

Si trabajas directamente con el puntero interno tendrás que trabajar con registros de tamaño fijo.

Imaginemos un registro clave-valor, donde la clave alcanzará como máximo 999 (3 bytes), mas un separador, p.ej.: '--' (2 bytes), más el campo valor (50 bytes, p.ej.). Entones tendremos cada registro con un tamaño fijo de 55 bytes. Entonces para cada linea el desplazamiento del puntero es de 55 bytes. De este modo podemos ir hacia adelante y hacia atras. Si el valor es mayor de 50 bytes lo tendremos que truncar antes de grabar.

Creo que me he explicado Smile

Mira este hilo a ver si te puede aclarar algo: https://foro.recursospython.com/showthread.php?tid=89
Responder
#7
Calvicius te pido mil disculpas si en ningún caso hice comentarios sobres tus post lo que ocurre es que cuando estoy embotado con algo me cuesta seguir el hilo de los demás, no obstante, ahora si estoy leyendo con detenimiento lo que escribiste y nota que hay muchas cosas que me sirven o que desconocía.
Bueno en definitiva y gracias a SEEK() me funciona a la perfección. -

Archivo
1 123
2 234
63 3663
1005 2005
print(codigo) ==> 1006

Código:
fo = open("practicas.txt", "r")
contenido = fo.read()
fo.seek(0, 0)

if contenido == '':
     codigo = 0
else:
    tmp = fo.readlines()[-1]
    tmp = tmp.split()
    codigo = int(tmp[0])

fo.close()
codigo += 1
print(codigo)

Un abrazo.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#8
me alegro que lo hayas resuelto.
Con todo lo que hemos debatido tienes todo un capitulo para estudiar Smile
saludos.

edito:

para saber si un fichero está vacío:

Código:
>>> import os
>>> os.stat("/tu/directorio/fichero.txt").st_size == 0
True
Responder
#9
De tanto leer en estos días había encontrado esa manera de saber si un fichero esta vacío o no, lo que no practique para saber donde deja el puntero en el archivo y en que sistemas operativos funciona. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#10
el puntero lo deja en la posición cero. Funciona en todos los SO

lo puedes probar asi:


Código:
import os
print(os.stat("salida.txt").st_size)
# >>> 21
with open('salida.txt', 'r') as f:
   lineas = f.read().splitlines()  # convertimos en una lista de lineas
   print(lineas)
   lineas_B = f.read().splitlines()
   print(lineas_B)
Responder


Salto de foro:


Usuarios navegando en este tema: 2 invitado(s)