TP3 - AlgoTwitter 2
Consigna
En este Trabajo Práctico 3, se requiere el desarrollo de un sistema para el manejo de tweets a través de archivos y directorios. El objetivo es implementar una aplicación que permita leer, guardar y recorrer tweets almacenados en el sistema de archivos, extendiendo las funcionalidades del TP2. Esto implica que todas las funcionalidades implementadas anteriormente deben seguir funcionando sin cambios en su comportamiento, y que además se deben incorporar las nuevas funcionalidades solicitadas en este TP. Este trabajo práctico incorpora dos nuevas funcionalidades: la importación/exportación masiva de tweets y la tokenización parametrizable. Además, agrega una capacidad clave al sistema: la persistencia de tweets en el sistema de archivos.
Importante:
Este Trabajo Práctico será evaluado con un sistema de pruebas automáticas. Por ello, es crítico respetar estrictamente los formatos especificados.
Tanto los mensajes por pantalla como los archivos generados o leídos deben ser exactamente iguales a los ejemplos presentados y a los lineamientos indicados. El cumplimiento de estos formatos es un requisito obligatorio para la aprobación.
Menú Principal
El menú principal debe ofrecer las siguientes opciones:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
Se mantienen las operaciones básicas de TP2 (crear, buscar y eliminar tweets). Se añaden las funcionalidades de importar y exportar.
De la misma manera que en el trabajo anterior, cuando se produce un caso que no permite la funcionalidad correcta, se deberá mostrar un mensaje de error especificado oportunamente. La totalidad de los errores serán detallados más adelante.
Ir ATRAS
se podrá realizar en cualquier momento de la ejecución del programa, a excepción del menú principal, donde será un INPUT_INVALIDO
.
A continuación, se detalla el funcionamiento de cada opción nueva, junto con el contrato que deben cumplir para que el TP sea considerado válido.
Como material complementario, se recomienda tener en cuenta:
- La sección de preguntas frecuentes relacionadas a archivos y excepciones.
- El apéndice 11.A del Apunte de la Materia, como ejemplo de un programa completo que considera archivos (¡ojo que no incluye manejo de excepciones!).
- El apéndice 12.A del Apunte de la Materia, como ejemplo de un programa con manejo de excepciones básicas.
4. Importar Tweet: Esta opción permite cargar uno o varios archivos .txt
; y uno o varios directorios que contengan archivos .txt
desde los cuales importar tweets
El usuario ingresa el número 4 para seleccionar la opción de importar tweets, seguido de la(s) ruta(s).
El programa debe responder con un mensaje de confirmación, incluyendo un número que identifica la cantidad de tweets agregados.
El programa debe responder con OK <cant_tweets>
, donde <cant_tweets>
es la cantidad de tweets agregados. Este formato debe ser respetado para asegurar el correcto funcionamiento de las pruebas automáticas.
Ejemplo de uso
Suponiendo un archivo en el directorio del trabajo práctico llamado tweets.txt
que contiene 3 líneas de texto diferentes, que representan 3 tweets.
El funcionamiento sería:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 4
Ingrese la ruta del archivo a cargar:
>>> tweets.txt
OK 3
Otro ejemplo de uso
Supongamos la siguiente estructura del trabajo práctico:
algo_twitter.py
carpeta1/
├ tweet1.txt (2 líneas → 2 tweets)
└ tweet2.txt (1 línea → 1 tweet)
carpeta2/
└ tweets2.txt (5 líneas → 5 tweets)
carpeta3/
└ carpeta4/
└ log.txt (1 línea → 1 tweet)
El funcionamiento sería:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 4
Ingrese la ruta del archivo a cargar:
>>> carpeta1 carpeta2/tweets2.txt carpeta3/carpeta4
OK 9
Como se puede observar, el usuario puede proporcionar rutas a archivos y directorios para cargar contenido de tweets. El programa debe:
Agregar por archivos
- Aceptar una o varias rutas de archivos
.txt
. - Cargar el contenido de tweets de cada archivo, en cualquier orden y sin filtros adicionales.
- Intentar cargar un archivo que no es
.txt
resulta una entrada inválida.
Agregar por directorios
- Aceptar una o varias rutas de directorios.
- Navegar por toda la estructura de cada directorio, incluyendo todos los niveles de subcarpetas, y cargar el contenido de tweets de todos los archivos
.txt
que encuentre. - Si un directorio (o sus subdirectorios) no contiene archivos
.txt
, simplemente no aporta tweets pero no detiene el procesamiento de otras rutas. - Si hay algún archivo que no es
.txt
en alguno de los directorios, se ignora.
Entrada mixta
- En una misma ejecución se pueden combinar rutas de archivos y de directorios.
- El programa procesará cada ruta indicada: leerá los archivos individuales y recorrerá cada directorio y sus subcarpetas para añadir todos los
.txt
disponibles.
Comportamiento general
- No hay garantía de orden en la carga de tweets; el objetivo es recopilar todo el contenido ubicado en las distintas rutas.
- Cada ruta se valida de forma independiente: si al menos una ruta no existe o no es accesible, se informará el error, como se indica más adelante.
- La importación no debe fallar en caso de que el directorio especificado sea válido pero no contenga archivos, o que todos los archivos presentes sean inválidos, o que todos los tweets dentro de un archivo sean inválidos.
Formato de entrada
- Cuando se indiquen varias rutas, deben separarse por espacios.
- No se admiten rutas que contengan espacios (por ejemplo: Mi carpeta/tweets de prueba.txt).
- Cada línea válida (!!) de estos archivos representa un tweet.
- Las líneas que no representen un tweet válido se deben ignorar.
Formato de salida
- Especificado:
OK <cant_tweets>
Casos de error
Si se ingresa una ruta a un archivo o directorio que no existe o que no representa un archivo de texto (.txt
), se debe mostrar el error ERROR_IMPORTACION
y volver a pedir una nueva ruta. Esto sucede siempre que alguna ruta sea inválida, aunque se indique junto a otras válidas.
Ante cualquier caso en el que no se pueda procesar un archivo, el programa debe mostrar ERROR_IMPORTACION
y volver a solicitar la ruta al usuario. Entre los escenarios que deben disparar este error se incluyen:
- Archivo inexistente: la ruta no apunta a ningún archivo en el sistema de archivos.
- Ruta inválida: la cadena ingresada contiene caracteres o formatos no reconocibles (por ejemplo, un espacio en el medio de la ruta, lo que la convierte en una ruta inválida).
- Archivo con extensión distinta: la ruta apunta a un archivo que no tiene extensión
.txt
. - Enlace roto o apuntando fuera de alcance: la ruta es un enlace simbólico que no resuelve en un archivo o directorio válido.
En cada uno de estos casos, tras mostrar ERROR_IMPORTACION
, el sistema debe esperar una nueva entrada y repetir la validación.
Ejemplo para un caso inválido:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 4
Ingrese la ruta del archivo a cargar:
>>> archivo_inexistente.txt
El/los archivos a importar deben existir y ser .txt válidos
Ingrese la ruta del archivo a cargar:
>>> archivo_existente.csv
El/los archivos a importar deben existir y ser .txt válidos
Ingrese la ruta del archivo a cargar:
>>> archivo_existente.txt archivo_inexistente.txt
El/los archivos a importar deben existir y ser .txt válidos
Ingrese la ruta del archivo a cargar:
>>> archivo_existente.txt archivo_existente.csv otro_archivo_existente.json
El/los archivos a importar deben existir y ser .txt válidos
Ingrese la ruta del archivo a cargar:
>>> archivo_inexistente.txt archivo_existente.csv
El/los archivos a importar deben existir y ser .txt válidos
Ingrese la ruta del archivo a cargar:
>>>
5. Exportar Tweet: Esta opción permite guardar todos los tweets actualmente en memoria a un archivo de texto
El usuario ingresa 5
para seleccionar la opción de exportar tweets, seguido de la ruta donde quiere crear el archivo.
El programa debe escribir cada tweet en una línea del archivo, y responder con OK <cant_tweets>
, donde <cant_tweets>
es la cantidad de tweets exportados. Este formato es obligatorio para el correcto funcionamiento de las pruebas automáticas.
Ejemplo de uso
Supongamos que en memoria hay 3 tweets y existe la carpeta data
en el directorio del trabajo práctico:
- "0. Primer tweet!"
- "1. Tweet intermedi@"
- "2. Último tweet"
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 5
Ingrese la ruta del archivo a guardar:
>>> data/tweets.txt
OK 3
Contenido de data/tweets.txt
(visto externamente):
Primer tweet!
Tweet intermedi@
Último tweet
Casos de error
Ante cualquier caso que no se pueda crear el archivo para exportar se debe mostrar el error DIRECCION_ERRONEA
y volver a pedirle al usuario otro ingreso.
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 5
Ingrese la ruta del archivo a guardar:
>>> tweets.csv
No se pudo exportar a esa dirección.
Ingrese la ruta del archivo a guardar:
>>>
En este caso, si se ingresa una ruta a un archivo que no es archivo de texto (.txt
) o si surge algún problema por el cual no se pueda exportar al archivo, se debe mostrar el error DIRECCION_ERRONEA
y volver a pedir una nueva ruta.
Formato de los archivos
- Cada archivo a exportar debe tener extensión
.txt
. - La ruta es relativa a dónde se encuentra el archivo
algo_twitter.py
. - Sólamente se debe soportar guardar en el directorio base del trabajo practico. Si se intenta guardar en un directorio que no existe, se debe mostrar el error
DIRECCION_ERRONEA
. - Cada tweet se escribe en una línea del archivo.
- No será impedimento para la exportación el hecho de que no se encuentren tweets almacenados en memoria.
Persistencia de datos
La persistencia de datos es una capacidad del sistema que garantiza que los tweets almacenados en memoria sobrevivan a cierres, interrupciones o reinicios, permitiendo su recuperación exacta en ejecuciones posteriores. El modelo de persistencia a ser implementado se detalla en el anexo de implementación sugerida para la persistencia de datos.
Requisitos
Estado persisitido entre sesiones
- Al cerrar el programa de forma ordenada (por ejemplo, eligiendo la opción 6) o por interrupciones inesperadas (Ctrl+C, corte de energía, kill, etc.), el sistema debe guardar automáticamente el último estado de los tweets.
- Al volver a iniciar, el estado recuperado debe ser idéntico al estado al momento del cierre.
Cobertura de información esencial
- Se debe persistir todo lo necesario para reconstruir el conjunto de tweets: sus identificadores únicos y su contenido completo (cada línea de texto).
Detección de corrupción de información
- Si al iniciar el programa se detecta que el almacenamiento está dañado, inaccesible o mal formateado, el sistema debe mostrar el error
DB_INVALIDA
:
Error al intentar abrir el programa.
y finalizar la ejecución de manera ordenada.
Consideraciones de implementación
El mecanismo de persistencia debe garantizar que:
- Cumpla los requisitos de integridad y recuperación completa.
- Maneje el guardado automático en cualquier tipo de cierre del programa.
- Detecte y notifique corrupciones con el error
DB_INVALIDA
. - Continúe garantizando la búsqueda y eliminación de tweets en menos que O(N) siendo N la cantidad de tweets/tokens de todos los tweets almacenados.
Ejemplo:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 4
Ingrese la ruta del archivo a cargar:
>>> tweets.txt
OK 3
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 2
Ingrese la/s palabra/s clave a buscar:
>>> Hola, ¿cómo estás?
Resultado de la busqueda:
0. Hola, ¿cómo estás?
>>> 6
Finalizando…
Luego, al volver a abrir una nueva sesión del algo_twitter:
$ python3 algo_twitter.py
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 2
Ingrese la/s palabra/s clave a buscar:
>>> Hola, ¿cómo estás?
Resultado de la busqueda:
0. Hola, ¿cómo estás?
Como se puede visualizar, se encuentran persistidos los tweets.
Tokenización parametrizable
El programa debe permitir especificar, opcionalmente, un parámetro desde la línea de comandos al ejecutarlo, que indique cual es el mínimo N (con N siendo un número natural mayor a cero) para tokenizar.
Modo de uso:
python3 algo_twitter.py <cantidad_de_tokens>
Por ejemplo:
python3 algo_twitter.py 4
Tener en cuenta que son comandos introducidos desde la consola, previo al inicio del programa, por lo que será necesario el uso de argv
.
Para lograr esto, la función main
deberá recibir args
, siendo éstos los comandos introducidos desde la consola y redireccionados a la función main. La función main
se verá de la siguiente manera:
def main(args):
...
if __name__ == "__main__":
args = # investigar cómo tomar los parámetros de argv
main(args)
De este modo, el programa usará una tokenización por segmentos con longitud mínima de 4 caracteres: cada palabra se fragmenta en segmentos de al menos N caracteres (aquí N = 4). Esto no descarta la tokenización por palabras previamente implementada.
No olvidar que esto debe ser compatible con la funcionalidad de persistencia de datos. Es decir, en diferentes ejecuciones del programa se podría requerir buscar sobre los mismos tweets con diferentes tokenizaciones, dando los resultados correspondientes.
Casos de error
Si no se proveyera una cantidad de tokens válida, el programa no podrá iniciarse, mostrando el error TOKENIZACION_INVALIDA
. En caso de que no se especifique ningún valor, se deberá utilizar por defecto una cantidad de tokens igual a 3.
$ python3 algo_twitter.py hola
El argumento de cantidad de tokens es inválido.
$ python3 algo_twitter.py -2
El argumento de cantidad de tokens es inválido.
Leer archivos de un directorio
Se recomienda tener en cuenta la función os.listdir()
del módulo
os
para identificar
los nombres de archivo dentro de un módulo. Tener en cuenta que la función puede
levantar las excepciones FileNotFoundError
y NotADirectoryError
.
Como extra, se puede considerar os.path.join()
del mismo
módulo para
considerar rutas en Windows y en Linux/macOS con el separador de carpetas
relevante (ver la entrada del FAQ: ¿Es lo mismo abrir un archivo en Windows que en Linux/macOS?).
En cuanto al uso del módulo os
, solo se permite el uso de os.listdir()
, os.path.join()
, os.path.isdir()
y os.path.exists()
. Para la elaboración del TP3, se restringe el uso de las otras funciones del módulo.
import os
directorio = "directorio-ejemplo"
nombres_archivos = os.listdir(directorio)
primer_ruta_completa = os.path.join(directorio, nombres_archivo[0])
with open(primer_ruta_completa) as archivo:
...
Considerando que un tweet puede contener diversos tipos de caracteres, si te sale algún error relacionado a la codificación del archivo al abrir e iterarlo, intentá abrirlo con with open(ruta, 'r', encoding='utf8')
.
Restricciones del formato de salida del programa
Para que sus trabajos pasen las pruebas del corrector automático, es muy importante mantener el formato utilizado en los ejemplos. Respetar el formato implica que todo lo que el programa muestre por pantalla debe ser exactamente igual a los ejemplos, sin textos adicionales ni cambios en los mensajes. Incluso pequeñas diferencias, como un espacio de más, un salto de línea extra o una palabra diferente, pueden hacer que las pruebas automáticas fallen.
Para facilitar esto, se proporcionan las constantes globales utilizadas en los tests. Utilícenlas en sus programas para evitar problemas de formato. Éstas complementan las constantes provistas en el Trabajo Práctico 2, realizado previamente.
ERROR_IMPORTACION = "El/los archivos a importar deben existir y ser .txt válidos"
DIRECCION_ERRONEA = "No se pudo exportar a esa dirección."
TOKENIZACION_INVALIDA = "El argumento de cantidad de tokens es inválido."
DB_INVALIDA = "Error al intentar abrir el programa."
RESULTADOS_BUSQUEDA = "Resultados de la busqueda:"
NO_ENCONTRADOS = "No se encontraron tweets."
TWEETS_ELIMINADOS = "Tweets eliminados:"
NUMERO_INVALIDO = "Numero de tweet invalido."
INPUT_INVALIDO = "Input invalido."
ATRAS = '**'
FIN = "Finalizando..."
DB_PATH = "db"
Es importante notar que no todos los textos que aparecen en los ejemplos se dan como constantes en esta sección. Se debe distinguir entre el texto que el programa muestra como salida (por ejemplo, a través de la función print
) y el texto que el usuario ingresa como entrada (por ejemplo, a través de la función input
). El formato de la salida debe coincidir exactamente con los ejemplos proporcionados. El formato de la entrada es más flexible y puede variar, siempre y cuando el programa pueda procesarla correctamente. Esto implica que el mensaje que se utiliza en un input no necesita seguir estos lineamientos. Por ejemplo, Ingrese la ruta del archivo a cargar: no figura como constante, dado que se utiliza en el input y no afecta el resultado de las pruebas automáticas. Sin embargo, el mensaje que se muestra al usuario como salida sí debe coincidir con los ejemplos.
De esta forma, todo mensaje de confirmación, así como también los mensajes provistos en las constantes, serán los únicos que el programa deba imprimir.
Por eso, se debe tener muy en cuenta que sobre todo lo que se haga print, será evaluado por el corrector automático.
Consejo: Si vas a debuggear tu código con prints, asegurate de sacarlos antes de entregar, ya que pueden afectar a la corrección de las pruebas automáticas.
Como recordatorio: cualquier entrada que no cumpla con el formato esperado (por ejemplo, al importar tweets) debe ser considerada como un input inválido. Esto incluye entradas vacías, caracteres no válidos, etc. En estos casos, se debe mostrar el mensaje INPUT_INVALIDO
y volver a solicitar la opción. Por ejemplo, si el usuario ingresa en el menú un número decimal o un texto en lugar de un número entero, se debe mostrar INPUT_INVALIDO
:
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 23
Input invalido.
1. Crear Tweet
2. Buscar Tweet
3. Eliminar Tweet
4. Importar tweets
5. Exportar tweets
6. Salir
>>> 6
Finalizando…
Retrocompatibilidad
La retrocompatibilidad garantiza que el TP3 sea 100% compatible con el TP2. Es decir, si ejecuto las pruebas del TP2 sobre el código del TP3, deben seguir pasando exactamente igual, sin cambios de comportamiento. Esto implica:
- Extender, no reemplazar: todas las funcionalidades nuevas se añaden sobre la base existente, sin alterar el flujo original.
- Módulos bien separados: diseñar código que aísle el del TP2 y los componentes adicionales, facilitando mantenimiento y crecimiento.
- Modificaciones mínimas: sólo realizar los ajustes estrictamente necesarios en el código del TP2 para habilitar la extensión; si terminás modificando gran parte del TP2, es señal de que la separación de responsabilidades debe revisarse.
Importante:
Como se mencionó anteriormente, la función main
ahora recibe args
. Es decir antes se invocaba solamente haciendo main()
y ahora main(args)
, esto puede ser problemático para la retrocompatibilidad.
Lo que se recomienda para este caso, es utilizar un parámetro “default” sobre ese argumento, en la definición de la función main()
de esta forma, llamar con el parámetro args
resulta utilizar esos argumentos, y llamarlo sin ese parámetro, resulta en los valores por defecto (en este caso con tokenización N=3
).
Restricciones de entrega
- El programa nunca debe finalizar con una excepción. En el caso de un error, se debe mostrar por pantalla al usuario el mensaje apropiado según fue especificado.
- No se permite el uso de ninguna biblioteca externa.
- El código debe ser eficiente, eligiendo las estructuras correctas para la solución de los problemas correspondientes.
- La entrega debe pasar todas las pruebas del corrector automático para ser considerada como tal.
- El código debe estar correctamente modularizado, documentado, y seguir las convenciones y buenas prácticas establecidas por el lenguaje y el curso.
- El uso de módulos de la biblioteca estándar de Python deberá ser previamente autorizada por un docente. Los siguientes módulos de la biblioteca estándar están permitidos sin previa autorización:
os
(solo para sus funcioneslistdir
,path.isdir
ypath.join
). - No se permite el uso del operador de argumentos * de la forma
funcion(*argumentos)
. - No se permite el uso de variables globales (sí el de constantes!).
- No se permite el uso de las instrucciones
eval
,exec
.
Entrega
La entrega como tal, puede variar según como haya decidido quien implementa el trabajo, puede ser uno o varios archivos. Lo único que se debe tener en cuenta es que el punto de entrada del TP es un archivo que se llame: algo_twitter.py
y que empiece su ejecución con la función main
.
La diferencia principal entre este TP y el anterior es que la función main
deberá recibir args
, siendo éstos los comandos introducidos desde la consola. La función main
se verá de la siguiente manera:
def main(args):
...
if __name__ == "__main__":
args = # investigar cómo tomar los parámetros de argv
main(args)
- Se deberán entregar únicamente los archivos .py que se utilicen. Siempre debe existir el archivo
algo_twitter.py
que contengamain()
. - La entrega se hará utilizando el formulario de entregas bajo la sección TP3.
- Una vez realizada la entrega, el sistema correrá las pruebas automáticas y te indicará si tu entrega cumple con las condiciones o no. Esto será inmediato, así que no es necesario cerrar la página ni esperar un mail.
- Si la entrega no cumple con las condiciones, podrás corregir y reenviar la entrega las veces que sea necesario hasta que cumpla con las condiciones, siempre y cuando se entregue antes de la primera o segunda fecha límite.
- Los detalles de los problemas encontrados en la entrega serán indicados por el sistema en el momento de la entrega.
Material
Este archivo contiene la base del trabajo práctico con las constantes y la definición del main necesarias para la entrega.
Anexo: Implementación sugerida para la persistencia de datos
Para cumplir con los requisitos de persistencia de datos detallados en la consigna, se propone un modelo específico basado en la creación de archivos individuales para cada tweet. Este enfoque facilitará la gestión de tweets entre sesiones y el manejo de la integridad de los datos.
Modelo de almacenamiento: un archivo por tweet
La idea central es utilizar un directorio llamado db
ubicado donde se encuentra el trabajo práctico (el algo_twitter.py
) como nuestra "base de datos". Dentro de este directorio, cada tweet se almacenará en su propio archivo de texto.
Para este modelo, las constantes aclaradas previamente en la consigna serán de utilidad:
DB_PATH = "db"
Estas constantes definen la ruta base del trabajo práctico y la ruta del directorio db
, donde se almacenarán los tweets. El directorio db
debe existir antes de iniciar el programa, y si no existe, se debe mostrar el error DB_INVALIDA
y finalizar la ejecución.
- Nombre del Archivo: Cada archivo se nombrará siguiendo el formato
N.txt
, dondeN
es el identificador único (ID) del tweet. Este ID debe ser un número entero, comenzando desde 0 y aumentando secuencialmente, de la misma forma que ocurre en el funcionamiento normal. - Contenido del Archivo: El contenido de cada archivo
N.txt
será únicamente el texto del tweet correspondiente, en una sola línea.
Ejemplo de Estructura de Archivos
Si tenemos tres tweets con IDs 0, 1 y 2, la estructura en el directorio sería:
algo_twitter.py
db/
├ 0.txt
├ 1.txt
└ 2.txt
Y el contenido de 0.txt
podría ser:
Este es mi primer tweet persistido!
Carga inicial del programa
Al iniciar algo_twitter.py
, el programa debe realizar las siguientes tareas para cargar los tweets existentes en memoria y prepararse para operar:
- Explorar el directorio: Leer todos los archivos presentes de tweets en el directorio
db
de la base de datos. - Cargar tweets válidos: Para cada archivo
N.txt
se deberá verificar si contiene un tweet válido y, de ser así, cargarlo en la sesión actual. - Determinar el próximo ID: Se deberá obtener el próximo ID a utilizar.
Operaciones y Persistencia
La clave de este modelo es que cada operación que modifique el estado de los tweets (crear o eliminar) debe reflejarse inmediatamente en el sistema de archivos. Esto garantiza la persistencia incluso ante cierres inesperados.
Crear Tweet
Crear un tweet implica, además de lo definido en el TP2, su almacenamiento en el directorio db/
para garantizar su persistencia.
Eliminar Tweet
Eliminar un tweet implica que el borrado del mismo también persistirá desde el momento de su eliminación. Se deberá actualizar la base de datos para asegurar que este tweet no forme parte del conjunto de tweets existentes y, además, que los IDs se mantengan consistentes. Se recomienda no eliminar el archivo del tweet borrado, pero si su contenido.
¿Por qué no eliminar el archivo al borrar?
Mantener el archivo N.txt
es importante para preservar la secuencia correcta de IDs. Si se eliminara el archivo de un tweet borrado, por ejemplo 2.txt
, cuando los IDs existentes eran 0, 1 y 2, el sistema podría identificar erróneamente a '1' como el ID más alto. Esto llevaría a que el siguiente tweet se cree con el ID '2', reutilizando un ID que ya fue asignado.
Ejemplo de Flujo
- Inicio: Carpeta
db
vacía.algo_twitter.py
inicia. Próximo ID = 0. - Crear T1: "Hola". Se crea
0.txt
con "Hola". Próximo ID = 1. - Crear T2: "Mundo". Se crea
1.txt
con "Mundo". Próximo ID = 2. - Crear T3: "Algo". Se crea
2.txt
con "Algo". Próximo ID = 3.db/
:0.txt
(Hola),1.txt
(Mundo),2.txt
(Algo).
- Eliminar T2 (ID 1): Se realizan las modificaciones sobre
1.txt
. Próximo ID = 3.db/
:0.txt
(Hola),1.txt
(eliminado),2.txt
(Algo).
- Cierre Inesperado.
- Reinicio:
algo_twitter.py
inicia.- Lee
0.txt
(carga "Hola"). - Lee
1.txt
(eliminado, ignora). - Lee
2.txt
(carga "Algo"). - Encuentra que el N máximo es 2. Próximo ID = 3.
- Lee
- Crear T4: "Twitter". Se crea
3.txt
con "Twitter". Próximo ID = 4.db/
:0.txt
(Hola),1.txt
(eliminado),2.txt
(Algo),3.txt
(Twitter).
Detección de Corrupción (DB_INVALIDA
)
Este modelo permite una detección básica de corrupción. Se debe mostrar el error DB_INVALIDA
y finalizar si no se pueden leer los archivos de nuestra base de datos por cualquier problema que surja con nuestro directorio db/
que implique que no se permita cargar los tweets correctamente. Este modelo aplica a todo el ciclo de vida del sistema, desde que se inicia el programa, durante toda su ejecución y hasta su finalización.
Importante:
Este modelo de persistencia debe implementarse de forma que no degrade el rendimiento de las operaciones de búsqueda y eliminación. La carga inicial en memoria es clave para mantener la eficiencia requerida (O(N)) para estas operaciones una vez que el programa está en ejecución. La escritura en disco después de cada acción asegura la persistencia, pero la lectura principal se hace solo al inicio.