9511_project03

project 3 for algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README LICENSE
commit 2d69a1ac6e1ea828c60759db91c4ce26308d45b1
parent 419878b94389b7edad5478e9e639bc86d24eabde
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Wed, 28 Jul 2021 18:54:16 -0300

Update: fusionated ADT_Vector_t with ADT_user_t

Diffstat:
MMakefile | 12+++++++++---
Mexamples/input_gen.py | 2+-
Minclude/cla.h | 2+-
Minclude/status.h | 1+
Minclude/user.h | 21+++++++++++++++++----
Minclude/vector.h | 12++++++++----
Msource/io.c | 40++++++++++++++++++++--------------------
Msource/main.c | 160++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Asource/main.c_orig | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/sort.c | 8++++----
Msource/user.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msource/vector.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
12 files changed, 522 insertions(+), 96 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,13 +1,13 @@
 CC=gcc
-CFLAGS=-pedantic -Wall
+CFLAGS=-pedantic -Wall -g
 SRCFOLDER=source
 HFOLDER=include
 PROGNAME=main
 
 all: main clean
 
-main: cla.o status.o sort.o io.o main.o user.o 
-    $(CC) $(CFLAGS) main.o cla.o status.o io.o sort.o user.o -o $(PROGNAME)
+main: cla.o status.o sort.o io.o main.o user.o vector.o
+    $(CC) $(CFLAGS) main.o cla.o status.o io.o sort.o user.o vector.o -o $(PROGNAME)
 
 main.o: $(HFOLDER)/cla.h $(HFOLDER)/status.h $(HFOLDER)/user.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/main.c
@@ -15,6 +15,9 @@ main.o: $(HFOLDER)/cla.h $(HFOLDER)/status.h $(HFOLDER)/user.h
 cla.o: $(HFOLDER)/cla.h $(HFOLDER)/status.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/cla.c
 
+vector.o: $(HFOLDER)/vector.h $(HFOLDER)/status.h
+    $(CC) $(CFLAGS) -c $(SRCFOLDER)/vector.c
+
 status.o: $(HFOLDER)/status.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/status.c
 
@@ -30,6 +33,9 @@ user.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
 clean:
     rm *.o
 
+run5:
+    ./main -fmt csv -out output.csv -in examples/test_file_5.csv -ti 1320498000 -tf 1320498046
+
 run20:
     ./main -fmt csv -out output.csv -in examples/test_file_20.csv -ti 1320498000 -tf 1320498046
 
diff --git a/examples/input_gen.py b/examples/input_gen.py
@@ -2,7 +2,7 @@ from string import digits
 from time import strftime, gmtime
 from random import randint, choice
 
-LINES = 50000000
+LINES = 5
 
 # OUTPUT:
 #     ID_TRANSACCION, ID_USUARIO, FECHA, MONTO, NUMERO DE TRAJETA, DESCRIPCION
diff --git a/include/cla.h b/include/cla.h
@@ -22,7 +22,7 @@ typedef enum {
 
 typedef struct {
     char *fmt, *fi, *fo;
-    unsigned long ti, tf, parsed_lines;
+    unsigned long ti, tf;
 } ADT_cla_t, *cla_t;
 
 status_t validate_arguments(int argc, char **argv);
diff --git a/include/status.h b/include/status.h
@@ -17,6 +17,7 @@ typedef enum {
     ERROR_MEMORY,
     ERROR_WRONG_FLAGS,
     ERROR_WRONG_TIME,
+    ERROR_INVALID_POS,
     ERROR_MISSING_ARGS,
     ERROR_OPENING_FILE,
     ERROR_CORRUPT_DATA,
diff --git a/include/user.h b/include/user.h
@@ -3,20 +3,33 @@
 
 #include "status.h"
 
+typedef unsigned long ulong;
+
 typedef struct {
-    size_t id;
-    long credit, debt;
+    /* id: user id / c: user credits / d: user debits */
+    ulong id, c, d;
 } ADT_user_t, *user_t;
 
 user_t user_find(const user_t *users, int id, size_t size);
 user_t user_dup(user_t src);
 
-status_t user_create(user_t *usr);
-status_t user_set_data(user_t *user, char **data);
+status_t user_create(ADT_user_t **);
+status_t user_set_data(ADT_user_t *, char **data);
+status_t user_add_amount(ADT_user_t *, long amount);
+
+int user_id_equal(const void *, const void *);
 
 void user_clean(user_t usr);
 
 status_t sort_users(user_t *users, size_t size, char *order);
 status_t destroy_users(user_t *users, size_t size);
 
+status_t user_printer(const void *, FILE *);
+
+int user_comparator(const void *, FILE *);
+
+int user_comparator_credits_minmax(const void *, const void *);
+int user_comparator_credits_maxmin(const void *, const void *);
+
+
 #endif
diff --git a/include/vector.h b/include/vector.h
@@ -9,11 +9,9 @@
 
 #include <stdlib.h>
 
-#include "types.h"
+#include "status.h"
 
 typedef status_t (*printer_t)(const void *, FILE *);
-/* typedef int (*comparator_t)(void *, void *); */
-
 typedef int (*comparator_t)(const void *, const void *);
 
 typedef struct {
@@ -21,6 +19,7 @@ typedef struct {
     size_t size, alloc;
 
     printer_t printer;
+    comparator_t comparator;
 
 } ADT_Vector_t;
 
@@ -29,10 +28,15 @@ status_t ADT_Vector_add(ADT_Vector_t **, void *);
 status_t ADT_Vector_destroy(ADT_Vector_t **);
 
 status_t ADT_Vector_load(ADT_Vector_t *, FILE *);
-status_t ADT_Vector_print(ADT_Vector_t *, FILE *);
+
+status_t ADT_Vector_set(ADT_Vector_t **, void *, size_t);
+status_t ADT_Vector_print(const ADT_Vector_t *, FILE *);
 status_t ADT_Vector_sort(ADT_Vector_t *, comparator_t);
 
+void *ADT_Vector_get_elem(const ADT_Vector_t *v, void *e);
+
 status_t ADT_Vector_set_printer(ADT_Vector_t *, printer_t);
+status_t ADT_Vector_set_comparator(ADT_Vector_t *, comparator_t);
 
 status_t ADT_Vector_export_as_xml(ADT_Vector_t *, FILE *, printer_t);
 status_t ADT_Vector_export_as_csv(ADT_Vector_t *, FILE *, printer_t);
diff --git a/source/io.c b/source/io.c
@@ -1,6 +1,8 @@
 #include "../include/io.h"
 
-/* Lee los datos del archivo de entrada linea por linea mientras los procesa y asigna a un arreglo de usuarios */
+
+/*
+//Lee los datos del archivo de entrada linea por linea mientras los procesa y asigna a un arreglo de usuarios
 status_t process_file(cla_t cla, user_t **users, size_t *size)
 {
     FILE *fpi;
@@ -10,7 +12,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
     user_t user, user_found, *tmp;
     status_t st;
 
-    *size = cla->parsed_lines = 0;
+    *size = 0;
     alloc_size = INIT_SIZE;
     user = user_found = NULL;
 
@@ -36,7 +38,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
         fclose(fpi);
     }
 
-    /* En caso de haber algun error users no es liberado, se libera luego en main */
+    //En caso de haber algun error users no es liberado, se libera luego en main
     if(((*users) = (user_t *)malloc(sizeof(user_t) * INIT_SIZE)) == NULL) {
         free(buffer);
         free(user);
@@ -44,9 +46,9 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
         fclose(fpi);
     }
 
-    /* Lee los datos de el archivo de entrada linea por linea */ 
+    //Lee los datos de el archivo de entrada linea por linea 
     while(fgets(buffer, BUFFER_SIZE, fpi) != NULL) {
-        /* Extiende el arreglo de usuarios en caso de que haya poca memoria */
+    //    Extiende el arreglo de usuarios en caso de que haya poca memoria
         if(*size == alloc_size) {
             alloc_size *= GROWTH_FACTOR;
             if((tmp = realloc((*users), alloc_size * sizeof(user_t))) == NULL) {
@@ -58,7 +60,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
             (*users) = tmp;
         }
 
-        /* Divide el buffer en subarreglos segun un caracter delimitador */
+    //    Divide el buffer en subarreglos segun un caracter delimitador
         if((st = string_split(buffer, data, INPUT_FILE_DELIM)) != OK) {
             fclose(fpi);
             free(buffer);
@@ -66,7 +68,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
             return st;
         }
 
-        /* Asigna a 'user' id, creditos y debitos cargados en data */
+    //    Asigna a 'user' id, creditos y debitos cargados en data
         if((st = user_set_data(&user, data)) != OK) {
             destroy_data(data);
             free(buffer);
@@ -74,7 +76,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
             return st;
         }
 
-        /* Transforma la fecha leida a tiempo UNIX en segundos */
+    //    Transforma la fecha leida a tiempo UNIX en segundos
         if((st = get_date(&epoch, data)) != OK) {
             destroy_data(data);
             free(buffer);
@@ -82,7 +84,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
             return st;
         }
 
-        /* Comprueba que la fecha leida este dentro del rango de fechas ingresadas en CLA */
+    //    Comprueba que la fecha leida este dentro del rango de fechas ingresadas en CLA
         if(epoch < cla->ti) continue;
         else if(epoch > cla->tf) {
             free(user);
@@ -92,20 +94,18 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
             return OK;
         }
 
-        /* Busca el numero de id en los usuarios ya ingresados, si no lo encuentra agrega un usuario nuevo al arreglo de usuarios */
+    //    Busca el numero de id en los usuarios ya ingresados, si no lo encuentra agrega un usuario nuevo al arreglo de usuarios
         if((user_found = user_find(*users, user->id, *size)) != NULL) {
-            user_found->credit += user->credit;
-            user_found->debt += user->debt;
+            user_found->c += user->c;
+            user_found->d += user->d;
         } else {
             (*users)[(*size)++] = user_dup(user);
         }
 
-        cla->parsed_lines++;
-
         user_clean(user);
         clean_data(data);
         clean_buffer(buffer);
-    } /* End while */
+    } // End while 
 
     free(user);
     destroy_data(data);
@@ -113,7 +113,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
     fclose(fpi);
     return OK;
 }
-
+*/
 
 status_t string_split(char *s, char **data, char *delim)
 {
@@ -121,7 +121,7 @@ status_t string_split(char *s, char **data, char *delim)
     size_t fields = 0;
 
     for(p = s; (tmp = strtok(p, delim)); p = NULL)
-        data[fields++] = strdup(tmp);
+        strcpy(data[fields++], tmp);
 
     if(fields != INPUT_FILE_FIELDS)
         return ERROR_CORRUPT_DATA;
@@ -172,7 +172,7 @@ status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size)
 
     for(i = 0; i < size; i++)
         fprintf(fo, "%ld%s%ld%s%ld\n", users[i]->id, CSV_OUTPUT_DELIM,\
-                users[i]->credit, CSV_OUTPUT_DELIM, users[i]->debt);
+                users[i]->c, CSV_OUTPUT_DELIM, users[i]->d);
 
     return OK;
 }
@@ -189,8 +189,8 @@ status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size)
     for(i = 0; i < size; i++) {
         fprintf(fo, "\t%s\n", XML_ROW_OPEN);
         fprintf(fo, "\t\t%s%ld%s\n", XML_ID_OPEN, users[i]->id, XML_ID_CLOSE);
-        fprintf(fo, "\t\t%s%ld%s\n", XML_CREDIT_OPEN, users[i]->credit, XML_CREDIT_CLOSE);
-        fprintf(fo, "\t\t%s%ld%s\n", XML_DEBT_OPEN, users[i]->debt, XML_DEBT_CLOSE);
+        fprintf(fo, "\t\t%s%ld%s\n", XML_CREDIT_OPEN, users[i]->c, XML_CREDIT_CLOSE);
+        fprintf(fo, "\t\t%s%ld%s\n", XML_DEBT_OPEN, users[i]->d, XML_DEBT_CLOSE);
         fprintf(fo, "\t%s\n", XML_ROW_CLOSE);
     }
 
diff --git a/source/main.c b/source/main.c
@@ -3,18 +3,25 @@
 #include "../include/user.h"
 #include "../include/sort.h"
 #include "../include/status.h"
+#include "../include/vector.h"
 
-/* "ca" - creditos ascendentes | "cd" - creditos descendentes
- * "da" - debitos ascendentes  | "dd" - debitos descendentes */
-#define SORTING_ORDER    "cd"
-#define PRINT_EXIT_SUCCESS_MSG
+#define BUFFER_INIT_SIZE    100
+#define INPUT_FILE_DELIM    ","
+#define INPUT_FILE_FIELDS    6    
 
 int main (int argc, char *argv[])
 {
     status_t st;
     cla_t cla;
-    user_t *users;
-    size_t size;
+    ADT_Vector_t *v;
+    ADT_user_t *user, *user_tmp;
+    char *b, *endptr;
+    char **data;
+    size_t i, j;
+    FILE *fi;
+    long amount;
+
+    user = NULL;
 
     /* Valida que los argumentos sean correctos */
     if((st = validate_arguments(argc, argv)) != OK) {
@@ -28,48 +35,151 @@ int main (int argc, char *argv[])
         return st;
     }
 
-    /* Asigna a la estructura 'cla' los argumentos ingresados */
-    if((st = cla_setup(argc, argv, &cla)) != OK) {
+    /* Crea un vector */
+    if((st = ADT_Vector_create(&v)) != OK) {
         show_status(st);
+        cla_destroy(&cla);
         return st;
     }
 
-    /* Carga en users los usuarios desde el archivo de entrada */
-    if((st = process_file(cla, &users, &size)) != OK) {
+    if((st = ADT_Vector_set_printer(v, user_printer)) != OK) {
         show_status(st);
         cla_destroy(&cla);
-        destroy_users(users, size);
+        ADT_Vector_destroy(&v);
         return st;
     }
 
-    /* Ordena los usuarios con orden SORTING_ORDER */
-    if((st = sort_users(users, size, SORTING_ORDER)) != OK) {
+    /* Asigna a la estructura 'cla' los argumentos ingresados */
+    if((st = cla_setup(argc, argv, &cla)) != OK) {
         show_status(st);
         cla_destroy(&cla);
-        destroy_users(users, size);
+        ADT_Vector_destroy(&v);
         return st;
     }
 
-    /* Imprime los datos cargados en users a un archivo de salida */
-    if((st = export_data(cla, users, size)) != OK) {
-        show_status(st);
+
+    b = calloc(sizeof(char), BUFFER_INIT_SIZE);
+    data = malloc(sizeof(char *) * INPUT_FILE_FIELDS);
+
+    if(b == NULL || data == NULL) {
+        free(b);
+        show_status(ERROR_MEMORY);
         cla_destroy(&cla);
-        destroy_users(users, size);
-        return st;
+        ADT_Vector_destroy(&v);
+        return ERROR_MEMORY;
+    }
+
+    /* Asigna memoria cada puntero dentro de data */
+    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
+        if((data[i] = calloc(sizeof(char), BUFFER_INIT_SIZE)) == NULL) {
+            show_status(ERROR_MEMORY);
+            for(j = 0; j < i; j++)
+                free(data[j]);
+
+            free(b);
+            cla_destroy(&cla);
+            ADT_Vector_destroy(&v);
+            return ERROR_MEMORY;
+        }
+    }
+        
+    /* Abre el archivo de entrada */
+    if((fi = fopen(cla->fi, "rt")) == NULL) {
+        show_status(ERROR_OPENING_FILE);
+        for(j = 0; j < INPUT_FILE_FIELDS; j++)
+            free(data[j]);
+
+        free(b);
+        cla_destroy(&cla);
+        ADT_Vector_destroy(&v);
+        return ERROR_OPENING_FILE;
+    }
+
+    ADT_Vector_set_comparator(v, user_id_equal);
+
+    user_tmp = NULL;
+    user_create(&user_tmp);
+
+    while(fgets(b, BUFFER_INIT_SIZE, fi)) {
+        string_split(b, data, INPUT_FILE_DELIM);
+        user_set_data(user_tmp, data);
+
+        amount = strtol(data[POS_AMOUNT], &endptr, 10);
+        if(*endptr != '\0') return ERROR_CORRUPT_DATA;
+
+        if((user = ADT_Vector_get_elem(v, user_tmp)) != NULL) {
+            /* El usuario ya existe */
+            user_add_amount(user, amount);
+        }
+        else { 
+            /* El usuario no existe */
+            user_create(&user);
+            user_set_data(user, data);
+            ADT_Vector_add(&v, user);
+        }
     }
 
+    ADT_Vector_sort(v, user_comparator_credits_maxmin);
+
+    ADT_Vector_print(v, stdout);
+
+    for(j = 0; j < INPUT_FILE_FIELDS; j++)
+        free(data[j]);
+
+    free(data);
+    free(b);
+    free(user_tmp);
+    fclose(fi);
+    cla_destroy(&cla);
+    ADT_Vector_destroy(&v);
+    return OK;
+}
+
+
+
+
+
+
+/*
+
+// "ca" - creditos ascendentes | "cd" - creditos descendentes
+// "da" - debitos ascendentes  | "dd" - debitos descendentes
+#define SORTING_ORDER    "cd"
+#define PRINT_EXIT_SUCCESS_MSG
+
+
 
 #ifdef PRINT_EXIT_SUCCESS_MSG
 
-    /* Imprime un mensaje para darle a conocer al usuario
-     * que todo se ejecuto correctamente    */
+    // Imprime un mensaje para darle a conocer al usuario
+    // que todo se ejecuto correctamente
     printf("\n%s\n%s%ld\n%s%ld\n", EXIT_SUCCESS_MSG, USERS_REGISTERED_MSG,\
             size, PROCESED_LINES_MSG, cla->parsed_lines);
 
 #endif
+*/
 
-    cla_destroy(&cla);
-    destroy_users(users, size);
 
-    return OK;
-}
+    /* Carga en users los usuarios desde el archivo de entrada */
+    /* if((st = process_file(cla, &users, &size)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
+
+    /* Ordena los usuarios con orden SORTING_ORDER */
+    /* if((st = sort_users(users, size, SORTING_ORDER)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
+
+    /* Imprime los datos cargados en users a un archivo de salida */
+    /* if((st = export_data(cla, users, size)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
diff --git a/source/main.c_orig b/source/main.c_orig
@@ -0,0 +1,182 @@
+#include "../include/io.h"
+#include "../include/cla.h"
+#include "../include/user.h"
+#include "../include/sort.h"
+#include "../include/status.h"
+#include "../include/vector.h"
+
+#define BUFFER_INIT_SIZE    100
+#define INPUT_FILE_DELIM    ","
+#define INPUT_FILE_FIELDS    6    
+
+int main (int argc, char *argv[])
+{
+    status_t st;
+    cla_t cla;
+    ADT_Vector_t *v;
+    user_t user;
+    char *b, *endptr;
+    char **data;
+    size_t i, j;
+    FILE *fi;
+    long id, amount;
+    void *up;
+
+    user = NULL;
+
+    /* Valida que los argumentos sean correctos */
+    if((st = validate_arguments(argc, argv)) != OK) {
+        show_status(st);
+        return st;
+    }
+
+    ADT_Vector_set_comparator(v, user_id_equal);
+
+    /* Asigna memoria a cla */
+    if((st = cla_create(&cla)) != OK) {
+        show_status(st);
+        return st;
+    }
+
+    /* Crea un vector */
+    if((st = ADT_Vector_create(&v)) != OK) {
+        show_status(st);
+        cla_destroy(&cla);
+        return st;
+    }
+
+    if((st = ADT_Vector_set_printer(v, user_printer)) != OK) {
+        show_status(st);
+        cla_destroy(&cla);
+        ADT_Vector_destroy(&v);
+        return st;
+    }
+
+    /* Asigna a la estructura 'cla' los argumentos ingresados */
+    if((st = cla_setup(argc, argv, &cla)) != OK) {
+        show_status(st);
+        cla_destroy(&cla);
+        ADT_Vector_destroy(&v);
+        return st;
+    }
+
+
+    b = calloc(sizeof(char), BUFFER_INIT_SIZE);
+    data = malloc(sizeof(char *) * INPUT_FILE_FIELDS);
+
+    if(b == NULL || data == NULL) {
+        free(b);
+        show_status(ERROR_MEMORY);
+        cla_destroy(&cla);
+        ADT_Vector_destroy(&v);
+        return ERROR_MEMORY;
+    }
+
+    /* Asigna memoria cada puntero dentro de data */
+    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
+        if((data[i] = calloc(sizeof(char), BUFFER_INIT_SIZE)) == NULL) {
+            show_status(ERROR_MEMORY);
+            for(j = 0; j < i; j++)
+                free(data[j]);
+
+            free(b);
+            cla_destroy(&cla);
+            ADT_Vector_destroy(&v);
+            return ERROR_MEMORY;
+        }
+    }
+        
+    /* Abre el archivo de entrada */
+    if((fi = fopen(cla->fi, "rt")) == NULL) {
+        show_status(ERROR_OPENING_FILE);
+        for(j = 0; j < INPUT_FILE_FIELDS; j++)
+            free(data[j]);
+
+        free(b);
+        cla_destroy(&cla);
+        ADT_Vector_destroy(&v);
+        return ERROR_OPENING_FILE;
+    }
+
+    while(fgets(b, BUFFER_INIT_SIZE, fi)) {
+        string_split(b, data, INPUT_FILE_DELIM);
+
+        id = strtol(data[POS_USER_ID], &endptr, 10);
+        if(*endptr != '\0') return ERROR_CORRUPT_DATA;
+
+        amount = strtol(data[POS_AMOUNT], &endptr, 10);
+        if(*endptr != '\0') return ERROR_CORRUPT_DATA;
+
+        if((user = (user_t)ADT_Vector_get_elem(v, user)) != NULL) {
+            /* El usuario ya existe */
+            user_add_amount(&user, amount);
+            printf("el usuario ya existe: %ld\n", user->id);
+        }
+        else { 
+            /* El usuario no existe */
+            user_create(&user);
+            user_set_data(&user, data);
+            /* user->id = id; */
+            /* user_add_amount(&user, amount); */
+        }
+
+        up = user;
+
+        ADT_Vector_add(&v, up);
+        /* printf("%ld\n", user->id); */
+    }
+
+    /* ADT_Vector_print(v, stdout); */
+    /* cla_destroy(&cla); */
+    /* ADT_Vector_destroy(&v); */
+    return OK;
+}
+
+
+
+
+
+
+/*
+
+// "ca" - creditos ascendentes | "cd" - creditos descendentes
+// "da" - debitos ascendentes  | "dd" - debitos descendentes
+#define SORTING_ORDER    "cd"
+#define PRINT_EXIT_SUCCESS_MSG
+
+
+
+#ifdef PRINT_EXIT_SUCCESS_MSG
+
+    // Imprime un mensaje para darle a conocer al usuario
+    // que todo se ejecuto correctamente
+    printf("\n%s\n%s%ld\n%s%ld\n", EXIT_SUCCESS_MSG, USERS_REGISTERED_MSG,\
+            size, PROCESED_LINES_MSG, cla->parsed_lines);
+
+#endif
+*/
+
+
+    /* Carga en users los usuarios desde el archivo de entrada */
+    /* if((st = process_file(cla, &users, &size)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
+
+    /* Ordena los usuarios con orden SORTING_ORDER */
+    /* if((st = sort_users(users, size, SORTING_ORDER)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
+
+    /* Imprime los datos cargados en users a un archivo de salida */
+    /* if((st = export_data(cla, users, size)) != OK) { */
+    /*     show_status(st); */
+    /*     cla_destroy(&cla); */
+    /*     destroy_users(users, size); */
+    /*     return st; */
+    /* } */
diff --git a/source/sort.c b/source/sort.c
@@ -5,7 +5,7 @@ int credit_minmax(const void *a, const void *b)
     user_t *A = (user_t *)a;
     user_t *B = (user_t *)b;
 
-    return ((*A)->credit > (*B)->credit) ? 1 : 0;
+    return ((*A)->c > (*B)->c) ? 1 : 0;
 }
 
 int credit_maxmin(const void *a, const void *b)
@@ -13,7 +13,7 @@ int credit_maxmin(const void *a, const void *b)
     user_t *A = (user_t *)a;
     user_t *B = (user_t *)b;
 
-    return ((*A)->credit > (*B)->credit) ? 0 : 1;
+    return ((*A)->c > (*B)->c) ? 0 : 1;
 }
 
 int debt_minmax(const void *a, const void *b)
@@ -21,7 +21,7 @@ int debt_minmax(const void *a, const void *b)
     user_t *A = (user_t *)a;
     user_t *B = (user_t *)b;
 
-    return ((*A)->debt > (*B)->debt) ? 1 : 0;
+    return ((*A)->d > (*B)->d) ? 1 : 0;
 }
 
 int debt_maxmin(const void *a, const void *b)
@@ -29,7 +29,7 @@ int debt_maxmin(const void *a, const void *b)
     user_t *A = (user_t *)a;
     user_t *B = (user_t *)b;
 
-    return ((*A)->debt > (*B)->debt) ? 0 : 1;
+    return ((*A)->d > (*B)->d) ? 0 : 1;
 }
 
 status_t sort_users(user_t *users, size_t l, char *order)
diff --git a/source/user.c b/source/user.c
@@ -1,13 +1,13 @@
 #include "../include/user.h"
 
-status_t user_create(user_t *usr)
+status_t user_create(ADT_user_t **user)
 {
-    if(((*usr) = (user_t)malloc(sizeof(ADT_user_t))) == NULL)
+    if((*user = (ADT_user_t *)malloc(sizeof(ADT_user_t))) == NULL)
         return ERROR_MEMORY;
 
-    (*usr)->id = 0;
-    (*usr)->credit = 0;
-    (*usr)->debt = 0;
+    (*user)->id = 0;
+    (*user)->c = 0;
+    (*user)->d = 0;
 
     return OK;
 }
@@ -15,38 +15,48 @@ status_t user_create(user_t *usr)
 void user_clean(user_t usr)
 {
     usr->id = 0;
-    usr->credit = 0;
-    usr->debt = 0;
+    usr->c = 0;
+    usr->d = 0;
 }
 
-status_t user_set_data(user_t *user, char **data) 
+status_t user_set_data(ADT_user_t *user, char **data) 
 {
     char *endptr;
     long amount;
 
     if(data == NULL || user == NULL) return ERROR_NULL_POINTER;
 
-    (*user)->id = strtol(data[POS_USER_ID], &endptr, 10);
+    user->id = strtol(data[POS_USER_ID], &endptr, 10);
     if(*endptr != '\0') return ERROR_CORRUPT_DATA;
 
     amount = strtol(data[POS_AMOUNT], &endptr, 10);
     if(*endptr != '\0') return ERROR_CORRUPT_DATA;
 
-    if(amount > 0) (*user)->credit = amount;
-    else if(amount < 0) (*user)->debt = -amount; /* '-=' Para eliminar el menos    */
+    if(amount > 0) user->c = amount;
+    else if(amount < 0) user->d = -amount; /* '-=' Para eliminar el menos    */
 
     return OK;
 }
 
-user_t user_dup(user_t src)
+status_t user_add_amount(ADT_user_t *user, long amount)
 {
-    user_t dst = NULL;
+    if(user == NULL) return ERROR_NULL_POINTER;
+
+    if(amount > 0) user->c += amount;
+    else if(amount < 0) user->d -= amount; /* '-=' Para eliminar el menos    */
+
+    return OK;
+}
+
+ADT_user_t *user_dup(user_t src)
+{
+    ADT_user_t *dst = NULL;
 
     user_create(&dst);
 
     dst->id = src->id;
-    dst->credit = src->credit;
-    dst->debt = src->debt;
+    dst->c = src->c;
+    dst->d = src->d;
 
     return dst;
 }
@@ -74,3 +84,56 @@ status_t destroy_users(user_t *users, size_t size)
     free(users);
     return OK;
 }
+
+status_t user_printer(const void *u, FILE *fp)
+{
+    if(u == NULL || fp == NULL) return ERROR_NULL_POINTER;
+
+    ADT_user_t *user = (ADT_user_t *)u;
+
+    fprintf(fp, "id: %6ld| credits: %6ld| debits: %6ld\n", user->id, user->c, user->d);
+
+    return OK;
+}
+
+int user_id_equal(const void *a, const void *b)
+{
+    ADT_user_t *A, *B;
+
+    if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
+
+    A = (ADT_user_t *)a;
+    B = (ADT_user_t *)b;
+
+    if(A->id == B->id) return 1;
+
+    return 0;
+}
+
+int user_comparator_credits_minmax(const void *a, const void *b)
+{
+    user_t A, B;
+
+    if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
+
+    A = *(user_t *)a;
+    B = *(user_t *)b;
+
+    if(A->c > B->c) return 1;
+    else if(A->c == B->c) return 0;
+    return -1;
+}  
+
+int user_comparator_credits_maxmin(const void *a, const void *b)
+{
+    user_t A, B;
+
+    if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
+
+    A = *(user_t *)a;
+    B = *(user_t *)b;
+
+    if(A->c < B->c) return 1;
+    else if(A->c == B->c) return 0;
+    return -1;
+}  
diff --git a/source/vector.c b/source/vector.c
@@ -1,14 +1,4 @@
-#include "vector.h"
-
-void swap(void *a, void *b)
-{
-    int *A = (int *)a;
-    int *B = (int *)b;
-
-    int tmp = *A;
-    *A = *B;
-    *B = tmp;
-}
+#include "../include/vector.h"
 
 status_t ADT_Vector_create(ADT_Vector_t **v)
 {
@@ -23,6 +13,7 @@ status_t ADT_Vector_create(ADT_Vector_t **v)
     (*v)->size = 0;
     (*v)->alloc = VECTOR_INIT_SIZE;
     (*v)->printer = NULL;
+    (*v)->comparator = NULL;
 
     return OK;
 }
@@ -80,7 +71,7 @@ status_t ADT_Vector_load(ADT_Vector_t *v, FILE *fi)
         tmp = (int *)malloc(sizeof(int));
 
         *tmp = (int)strtol(b, &endptr, 10);
-        if(*endptr != '\n') return ERROR_CORRUPT_FILE;
+        if(*endptr != '\n') return ERROR_CORRUPT_DATA;
 
         ADT_Vector_add(&v, tmp);
 
@@ -90,7 +81,60 @@ status_t ADT_Vector_load(ADT_Vector_t *v, FILE *fi)
     return OK;
 }
 
-status_t ADT_Vector_print(ADT_Vector_t *v, FILE *fp)
+status_t ADT_Vector_set(ADT_Vector_t **v, void *e, size_t pos)
+{
+    void ** aux;
+    size_t i, alloc_size;
+
+    if(v == NULL || e == NULL) return ERROR_NULL_POINTER;
+    else if(pos > (*v)->size) return ERROR_INVALID_POS;
+
+    alloc_size = (*v)->alloc;
+
+    /* Cuenta cuanto tiene que alargar el arreglo p/ que entre el nuevo elemento */
+    while(pos >= alloc_size) {
+        alloc_size *= VECTOR_GROWTH_FACTOR;
+    }
+
+    /* Extiende el arreglo en caso de que no haya memoria suficiente */
+    if(pos > (*v)->alloc) {
+        if((aux = (void **)realloc((*v)->a, sizeof(void *) * alloc_size)) == NULL)
+            return ERROR_MEMORY;
+        else {
+            (*v)->a = aux;
+            (*v)->alloc = alloc_size;
+        }
+    }
+
+    for(i = (*v)->size; i < pos; i++) {
+        (*v)->a[pos] = NULL;
+    }
+
+    (*v)->a[pos] = e;
+
+    if(pos >= (*v)->size) {
+        (*v)->size = (pos + 1);
+    }
+
+    return OK;
+}
+
+void *ADT_Vector_get_elem(const ADT_Vector_t *v, void *e)
+{
+    size_t i;
+
+    if(v == NULL || e == NULL) return NULL;
+
+    for(i = 0; i < v->size; i++) { 
+        if(v->comparator(e, v->a[i])) {
+            return v->a[i];
+        }
+    }
+
+    return NULL;
+}
+
+status_t ADT_Vector_print(const ADT_Vector_t *v, FILE *fp)
 {
     size_t i;
 
@@ -107,12 +151,6 @@ status_t ADT_Vector_sort(ADT_Vector_t *v, comparator_t pf)
 {
     if(v == NULL) return ERROR_NULL_POINTER;
 
-    /* Bubble sort */
-    /* for(size_t i = 0; i < v->size; i++) */
-    /*     for(size_t j = 0; j < (v->size - i - 1); j++) */
-    /*         if(pf(v->a[j], v->a[j + 1]) > 0) */
-    /*             swap(v->a[j], v->a[j + 1]); */
-
     /* Quick sort */
     qsort(v->a, v->size, sizeof(void *), pf);
 
@@ -128,6 +166,15 @@ status_t ADT_Vector_set_printer(ADT_Vector_t *v, printer_t pf)
     return OK;
 }
 
+status_t ADT_Vector_set_comparator(ADT_Vector_t *v, comparator_t pf)
+{
+    if(v == NULL) return ERROR_NULL_POINTER;
+
+    v->comparator = pf;
+
+    return OK;
+}
+
 status_t ADT_Vector_export_as_csv(ADT_Vector_t *v, FILE *fp, printer_t pf)
 {
     status_t st;