Está en la página 1de 14

Tecnicatura Universitaria en

Programación
Seminario de Tecnología

GUIA DE LA UNIDAD 8
Contenidista: Prof. Diana Cicinelli
INDICE – Guía 8

1. INTRODUCCIÓN ................................................................................................................ 4

1.1 Operaciones principales sobre el archivo binario ................................................ 4


1.2 Operaciones adicionales ................................................................................................. 5
1.3 Aplicación ............................................................................................................................. 5
SÍNTESIS DE LA UNIDAD .................................................................................................... 14
ACTIVIDAD 1 Tarea............................................................................................................... 14

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 2


MAPA DE LA GUIA 1: Archivos Binarios

OBJETIVOS:
En esta Unidad esperamos que el estudiante pueda

● Conocer qué es un archivo binario


● Saber realizar altas, bajas y modificaciones en un archivo bnario

CONTENIDOS:
1. INTRODUCCIÓN

PALABRAS CLAVE

Módulo Pickle-archivo binario

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 3


1. INTRODUCCIÓN

A continuación, vamos estudiar cómo realizar altas, bajas y modificaciones en un


archivo binario usando el módulo Pickle.
Un archivo binario guarda la información de la misma forma que la encuentra en
memoria, por lo tanto, no es legible con un editor de texto como sí lo es un archivo
de tipo texto, por tal motivo, un archivo binario se lo crea y se lo procesa desde un programa
que comúnmente denominamos ABM (alta-baja-modificación). En un archivo binario, los datos,
se almacenan en registros, en nuestro caso vamos a usar la tupla que es lo más parecido a un
registro que tiene Python.

El paquete Pickle se encarga de la lectura/escritura en archivos binarios. Posee dos funciones


fundamentales: load() y dump(). La primera sirve para leer desde el archivo y la segunda para
grabar datos en el archivo.

También, vamos a utilizar las funciones tell() y seek() que ya estudiamos, además de las
funciones open() y close().

El archivo binario almacena un registro a continuación de otro en forma secuencial pero acepta
el acceso directo. Generalmente, se usa una clave para acceder a los datos. La clave es un campo
del registro cuyo valor no se repite, es decir, dos datos no pueden tener la misma clave. Ejemplos
de claves: DNI para una persona, código de producto para un artículo en venta, ISBN para un
libro, etc.

Todos los registros deben tener el mismo tamaño.

1.1 Operaciones principales sobre el archivo binario

 Alta: para dar de alta un nuevo registro, primero se debe hacer una búsqueda para
verificar que la clave no exista, es decir, que no se encuentre un registro con igual
clave. El nuevo registro se lo agrega al final del archivo, para ello abrimos el archivo
en el modo “a+b” que indica que el archivo es abierto para append y poder grabar
en él.

 Baja: en este caso, se debe buscar la clave del registro a dar de baja. Dar de baja un
registro nos abre la puerta a un problema. Este problema es que no podemos dejar
huecos entre un registro y su siguiente, por lo tanto, lo que se hace es dar de baja
el registro de manera lógico, se lo marca de tal forma que sabemos que ese registro
no existe más después de darle de baja. Para marcar el registro podemos usar la

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 4


misma clave del registro sobre-escribiendo el campo con un valor que
reconozcamos como dado de baja. Otra forma de dar de baja de forma lógica es
agregando un campo extra que tome un valor lógico o entero o carácter que indique
que el registro fue dado de baja. En este caso, la apertura del archivo lo hacemos
con el modo “r+b”, que indica que se abre para lectura/escritura.
 Modificación: se debe buscar la clave, el registro a modificar debe existir. Se sobre-
escribe el registro con los nuevos valores. Al igual que en la baja, abrimos el archivo
en el modo “r+b”.

1.2 Operaciones adicionales

 Listado: los listados pueden ser de todos los datos o pueden contener los datos
filtrados por uno o más campos. En este caso, sólo vamos a leer desde el archivo
para mostrar por pantalla, por lo tanto, la apertura del archivo es sólo lectura.
 Compactación/depuración: cuando se acumulan los registros dados de baja es
necesario borrarlos físicamente para que no ocupen lugar. En este proceso se usa
un archivo auxiliar para copiar en él todos los registros que aún están activos y luego
se eliminar el archivo original. El archivo auxiliar se lo abre para escritura mientras
que el archivo original se lo abre para lectura.

1.3 Aplicación

Desarrollar un programa con un menú de opciones, que permita realizar en forma completa
la gestión ABM de un archivo de registros de estudiantes de una carrera universitaria. Por
cada estudiante, prevea tres campos para el legajo, el nombre y el promedio (además del
campo de marcado lógico para las bajas lógicas). El programa debe incluir opciones que
permitan:

 Realizar altas de registros.


 Realizar bajas lógicas.
 Realizar la modificación de los datos de un registro.
 Mostrar el contenido completo del archivo.
 Mostrar los datos de los estudiantes con promedio mayor o igual a 7.
 Realizar la depuración del archivo (proceso de bajas físicas).

Resolución:

Para resolver este problema, vamos a tener que usar, además del paquete Pickle, los paquetes
io (entrada/salida), os (sistema operativo).

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 5


La información que ingresamos por teclado va a estar totalmente validada, para ello, vamos a
usar funciones que validan el legajo y el promedio de un alumno. Otra función que nos será útil
realizará la conversión de la tupla a una cadena de caracteres para poder mostrar la tupla por
pantalla de una manera legible.

A continuación, mostramos el listado de estas tres funciones:

def toString(est):
legajo,nombre,promedio,activo = est
r = ''
r += '{:<20}'.format('Legajo: '+ str(legajo))
r += '{:<30}'.format('Nombre: '+ nombre.strip())
r += '{:<20}'.format('Precio: '+ str(promedio))
return r

def validarLegajo(inf,sup):
n = inf - 1
while n < inf or n > sup:
n = int(input("Entre "+str(inf)+' y '+str(sup)+' por favor: '))
return n

def validarPromedio():
n = -1.0
while n < 0 or n > 10:
n = float(input('Entre 0 y 10 por favor (acepta decimales): '))
return n

Para poder dar de alta, baja o realizar una modificación, vamos a necesitar una función de
búsqueda. Esta función recorre registro por registro buscando una clave determinada, cuando
encuentra el registro con la clave buscada, la función retorna la ubicación del registro en bytes
dentro del archivo. El puntero del archivo debe volver a la posición en la cual se encontraba.
Para hacer esta búsqueda van a ser necesarias las funciones tell() y seek(), la primera para saber
a partir de qué byte se encuentra el registro buscado y la segunda para reposicionar el puntero
del archivo a la posición donde se encontraba antes de la búsqueda.
El paquete io provee de tres constantes que son usadas por seek() para posicionarse dentro del
archivo. Estas constantes son: io.SEEK_SET (posición inicial) , io.SEEK_CUR (posición actual),
io.SEEK_END (posición final, donde se encuentra la marca de fin de archivo).
Python no tiene una función que detecte el fin del archivo, para detener la búsqueda del registro
se obtiene el tamaño en bytes del archivo y se controla que el puntero del archivo no se pase
de ese valor. La función que obtiene el tamaño del archivo es getsize() del paquete os.path.

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 6


def buscar(m, leg, FD):
t = os.path.getsize(FD)
fpInicio = m.tell()
m.seek(0, io.SEEK_SET)
posicion = -1
while m.tell() < t:
fp = m.tell()
est = pickle.load(m)
legajo,nombre,promedio,activo = est
if activo and legajo == leg:
posicion = fp
break
m.seek(fpInicio, io.SEEK_SET)
return posición

Otra función útil es la función flush(), esta función se encarga de “fluir” el buffer del archivo.
Fuerza que los datos que se encuentran en el buffer sean grabados en el archivo. Esta función
se usará cada vez que se deba grabar el registro en el archivo.

Como los registros deben tener todos el mismo tamaño, el campo nombre del alumno, se lo
ajusta a 30 caracteres con la función ljust().

A continuación, mostramos el listado completo del programa:

import io
import os
import os.path
import pickle

def toString(est):
legajo,nombre,promedio,activo = est
r = ''
r += '{:<20}'.format('Legajo: '+ str(legajo))
r += '{:<30}'.format('Nombre: '+ nombre.strip())
r += '{:<20}'.format('Precio: '+ str(promedio))
return r

def validarLegajo(inf,sup):
n = inf - 1

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 7


while n < inf or n > sup:
n = int(input("Entre "+str(inf)+' y '+str(sup)+' por favor: '))
return n

def validarPromedio():
n = -1.0
while n < 0 or n > 10:
n = float(input('Entre 0 y 10 por favor (acepta decimales): '))
return n

def buscar(m, leg, FD):


t = os.path.getsize(FD)
fpInicio = m.tell()
m.seek(0, io.SEEK_SET)
posicion = -1
while m.tell() < t:
fp = m.tell()
est = pickle.load(m)
legajo,nombre,promedio,activo = est
if activo and legajo == leg:
posicion = fp
break
m.seek(fpInicio, io.SEEK_SET)
return posicion

def alta(FD):
m = open(FD, 'a+b')
print()
print("ingrese legajo a dar de alta <0: salir>: ")
leg = validarLegajo(0,99999)
while leg != 0:
pos = buscar(m,leg,FD)
if pos == -1: #no existe, se puede dar de alta
nom = input("Nombre: ")
nom = nom.ljust(30, ' ') #completa 30 caracteres
print("Promedio: ")
pro = validarPromedio()
est = (leg, nom, pro, True)
pickle.dump(est,m)

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 8


m.flush() # el S.O. lo baja al archivo
print("registro grabado")
else:
print("registro existente")
print()
print("ingrese otro legajo <0:salir>")
leg = validarLegajo(0,99999)
m.close()
input("presione <Enter> para continuar")

def baja(FD):
if not os.path.exists(FD):
print('El archivo', FD, 'no existe...')
print()
return
m = open(FD, 'r+b')
print()
print("ingrese legajo a dar de alta <0: salir>: ")
leg = validarLegajo(0,99999)
while leg != 0:
pos = buscar(m, leg, FD)
if pos != -1:
m.seek(pos, io.SEEK_SET)
est = pickle.load(m)
legajo,nombre,promedio,activo = est
print()
print("Registro grabado: ", toString(est))
r = input("desea borrarlo (s/n)?: ")
if r in "sS":
activo = False
est = (legajo,nombre,promedio,activo)
m.seek(pos, io.SEEK_SET)
pickle.dump(est,m)
print("registro eliminado: ")
else:
print("registro inexistente")
print("ingrese otro registro para dar de baja <0:salir>: ")
leg = validarLegajo(0,99999)
m.close()

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 9


input("presione <Enter> para continuar")

def modificacion(FD):
if not os.path.exists(FD):
print('El archivo', FD, 'no existe...')
print()
return
m = open(FD, 'r+b')
print()
print("ingrese legajo a dar de alta <0: salir>: ")
leg = validarLegajo(0,99999)
while leg != 0:
pos = buscar(m, leg, FD)
if pos != -1:
m.seek(pos, io.SEEK_SET)
est = pickle.load(m)
legajo,nombre,promedio,activo = est
print()
print("Registro grabado: ", toString(est))
op = 0
while op != 3:
print("1. modificar nombre.")
print("2. modificar promedio. ")
print("3. salir ")
op = int(input("\t\tIngrese opcion: "))
if op == 1:
nom = input("Ingrese nombre: ")
nombre = nom.ljust(30,' ')
elif op == 2:
promedio = validarPromedio()
elif op == 3:
pass
m.seek(pos, io.SEEK_SET)
est = (legajo,nombre,promedio,activo)
pickle.dump(est,m)
else:
print("el registro no existe")
print("ingrese nuevo legajo: ")
leg = validarLegajo(0,99999)

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 10


m.close()
input("presione <Enter> para continuar")

def listadoCompleto(FD):
if not os.path.exists(FD):
print('El archivo', FD, 'no existe...')
print()
return
tbm = os.path.getsize(FD)
m = open(FD,'rb')
print("*"*74)
while m.tell() < tbm:
est = pickle.load(m)
legajo,nombre,promedio,activo = est
if activo:
print("* "+toString(est)+" *")
print("*"*74)
m.close()
input("presione <Enter> para continuar")

def listadoConFiltro (FD, filtro):


if not os.path.exists(FD):
print('El archivo', FD, 'no existe...')
print()
return
tbm = os.path.getsize(FD)
m = open(FD,'rb')
while m.tell() < tbm:
est = pickle.load(m)
legajo,nombre,promedio,activo = est
if activo and promedio >= filtro:
print(toString(est))
m.close()
input("presione <Enter> para continuar")

def depuracion(FD):
if not os.path.exists(FD):
print('El archivo', FD, 'no existe...')
print()

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 11


return
tbm = os.path.getsize(FD)
original = open(FD, 'rb')
temporal = open("temporal.dat","wb")
while original.tell()< tbm:
est = pickle.load(original)
legajo,nombre,promedio,activo = est
if activo:
pickle.dump(est, temporal)
original.close()
temporal.close()
os.remove(FD)
os.rename("temporal.dat",FD)
print("fueron eliminados los registros marcados")
input("presione <Enter> para continuar")

def menu ():


print('Opciones ABM del archivo de estudiantes')
print(' 1. Alta de estudiantes')
print(' 2. Baja de estudiantes')
print(' 3. Modificación de estudiantes')
print(' 4. Listado completo de estudiantes')
print(' 5. Listado de estudiantes con promedio >= a 7')
print(' 6. Depuración del archivo de estudiantes')
print(' 7. Salir')
op = int(input('\t\tIngrese número de la opción elegida: '))
return op

###programa principal
FD = "estudiante2.dat"
op = menu()
while op != 7:
if op == 1:
alta(FD)
if op == 2:
baja(FD)
if op == 3:
modificacion(FD)
if op == 4:

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 12


listadoCompleto(FD)
if op == 5:
listadoConFiltro(FD,7)
if op == 6:
depuracion(FD)
op = menu()

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 13


SÍNTESIS DE LA UNIDAD

La persistencia de la información es una herramienta que permite recuperar la información para


procesarla más tarde. Una de las tareas más importantes que se realiza con los archivos de tipo
binario es el ABM (alta-baja-modificación). A estas tres operaciones básicas podemos agregar la
consulta para mostrar los datos de un registro en particular sin modificarlo. Realizar un ABM
involucra operaciones extras como la búsqueda de un registro y otras operaciones que no tienen
que ver con los archivos de forma directa, pero son necesarias para que el sistema funcione
correctamente como las validaciones de la información.

ACTIVIDAD 1 Tarea

Le pedimos que realice la Actividad que le proponemos en el campus y la envíe al tutor


para su corrección.

Le pedimos que realice la Actividad que le proponemos en el campus de manera


de ir afianzando conceptos vistos hasta aquí.

SEMINARIO DE TECNOLOGÍA – UNIDAD 8 14

También podría gustarte