9511_project03

project 3 for algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README LICENSE
commit 6a255581fa73bc0f5a12ea53a0b26e3b9c0a8c73
parent 037c246f134873305f86d3ccc3a38ec29308ff66
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Fri,  6 Aug 2021 20:38:23 -0300

Getting ready to deliver 'entrega_3'

Diffstat:
Mexamples/input_gen.py | 6+++---
Minclude/load.h | 2++
Minclude/user.h | 2+-
Minclude/vector.h | 5++---
Msource/load.c | 90++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msource/user.c | 31++++++++++++++-----------------
Msource/utils.c | 2+-
Msource/vector.c | 57+++++++++++++++++++++++++--------------------------------
8 files changed, 98 insertions(+), 97 deletions(-)
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 = 10000
+LINES = 15
 
 # OUTPUT:
 #     ID_TRANSACCION, ID_USUARIO, FECHA, MONTO, NUMERO DE TRAJETA, DESCRIPCION
@@ -92,9 +92,9 @@ def generate_card(type):
 def generate_file(max_lines):
     id_transaction_base = 123400
     id_user_base = 1
-    id_user_max = 30000
+    id_user_max = 10
     amount_base = 1
-    amount_max = 10000
+    amount_max = 100
     for i in range(max_lines):
         id_transaction = (i + id_transaction_base)
         id_user = randint(id_user_base, id_user_max)
diff --git a/include/load.h b/include/load.h
@@ -7,6 +7,8 @@
 #include "../include/vector.h"
 #include "../include/status.h"
 
+#define STR_MSG_END_PROCSS    "End processing input file\nLines processed: "
+
 status_t load_users_to_vector(ADT_Vector_t **, ADT_cla_t *);
 
 #endif
diff --git a/include/user.h b/include/user.h
@@ -14,9 +14,9 @@ typedef struct {
 } ADT_user_t;
 
 status_t user_create(ADT_user_t **);
+status_t user_dup(ADT_user_t *, ADT_user_t *);
 status_t user_destroy(ADT_user_t **);
 
-status_t user_set_data_from_str(ADT_user_t *, char **);
 status_t user_set_data(ADT_user_t *, ulong, ulong, ulong);
 
 status_t user_add_amount(ADT_user_t *, long);
diff --git a/include/vector.h b/include/vector.h
@@ -28,12 +28,11 @@ status_t ADT_Vector_create(ADT_Vector_t **);
 status_t ADT_Vector_add(ADT_Vector_t **, void *);
 status_t ADT_Vector_destroy(ADT_Vector_t **);
 
-status_t ADT_Vector_set_elem(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 *, void *);
-
+status_t ADT_Vector_set_elem(ADT_Vector_t **, void *, size_t);
+status_t ADT_Vector_get_elem(const ADT_Vector_t *, void **, size_t);
 status_t ADT_Vector_get_elem_pos(const ADT_Vector_t *, void *, size_t *);
 
 status_t ADT_Vector_set_printer(ADT_Vector_t *, printer_t);
diff --git a/source/load.c b/source/load.c
@@ -4,10 +4,11 @@ status_t load_users_to_vector(ADT_Vector_t **v, ADT_cla_t *cla)
 {
     status_t st;
     char buffer[IN_FILE_MAX_LEN];
-    char *endptr, **data;
-    ADT_user_t *user, *user_tmp;
+    char *endptr1, *endptr2, **data;
+    ADT_user_t *u1, *u2, *u3;
     time_t epoch;
     long long amount;
+    size_t user_pos, parsed_lines;
     ulong id, c, d;
 
     if(v == NULL || cla == NULL) return ERROR_NULL_POINTER;
@@ -15,29 +16,24 @@ status_t load_users_to_vector(ADT_Vector_t **v, ADT_cla_t *cla)
     if((st = create_2darray(&data, IN_FILE_FIELDS, IN_FILE_FIELDS_MAX_LEN)) != OK)
         return st;
 
-    /* Crea un usuario temporal */
-    if((st = user_create(&user_tmp)) != OK) {
-        destroy_2darray(data, IN_FILE_FIELDS);
-        return st;
-    }
-
+    parsed_lines = 0;
     while(fgets(buffer, IN_FILE_MAX_LEN, cla->fi)) {
-        if((st = string_split(buffer, data, IN_FILE_DELIM)) != OK) {
-            free(user_tmp);
+        if((st = user_create(&u1)) != OK) {
             destroy_2darray(data, IN_FILE_FIELDS);
             return st;
         }
 
-        id = strtol(data[POS_USER_ID], &endptr, 10);
-        if(*endptr != '\0') {
-            free(user_tmp);
+        if((st = string_split(buffer, data, IN_FILE_DELIM)) != OK) {
+            free(u1);
             destroy_2darray(data, IN_FILE_FIELDS);
-            return ERROR_CORRUPT_DATA;
+            return st;
         }
 
-        amount = strtol(data[POS_AMOUNT], &endptr, 10);
-        if(*endptr != '\0') {
-            free(user_tmp);
+        id = strtol(data[POS_USER_ID], &endptr1, 10);
+        amount = strtol(data[POS_AMOUNT], &endptr2, 10);
+
+        if(*endptr1 || *endptr2) {
+            free(u1);
             destroy_2darray(data, IN_FILE_FIELDS);
             return ERROR_CORRUPT_DATA;
         }
@@ -45,14 +41,14 @@ status_t load_users_to_vector(ADT_Vector_t **v, ADT_cla_t *cla)
         if(amount > 0) { c = amount; d = 0; }
         else if(amount < 0) { c = 0; d = -amount; }
 
-        if((st = user_set_data(user_tmp, id, c, d)) != OK) {
-            free(user_tmp);
+        if((st = user_set_data(u1, id, c, d)) != OK) {
+            free(u1);
             destroy_2darray(data, IN_FILE_FIELDS);
             return ERROR_CORRUPT_DATA;
         }
 
         if((st = get_date(&epoch, data[POS_TXN_DATE])) != OK){
-            free(user_tmp);
+            free(u1);
             destroy_2darray(data, IN_FILE_FIELDS);
             return ERROR_CORRUPT_DATA;
         }
@@ -63,48 +59,62 @@ status_t load_users_to_vector(ADT_Vector_t **v, ADT_cla_t *cla)
 
         /* Comprueba que la tarjeta usada en la transaccion sea la correcta */
         if(!is_valid_card(data[POS_CARD_NUMBER])) {
-            fprintf(stderr, "%s: %s\n",STR_INVALID_CARD_NUMBER, data[POS_CARD_NUMBER]);
+            fprintf(stderr, "%s: %s\n", STR_INVALID_CARD_NUMBER, data[POS_CARD_NUMBER]);
             continue;
         }
 
         /* Busca el id del usuario en el vector */
-        if((user = ADT_Vector_get_elem(*v, user_tmp)) != NULL) {
-            /* Si lo encuentra le suma el monto correspondiente */
-            if((st = user_add_amount(user, amount)) != OK) {
+        if((st = ADT_Vector_get_elem_pos(*v, u1, &user_pos)) == OK) {
+            /* Si llega aca lo encontrĂ³, entonces se lo asigna a un usuario temporal */
+            if((st = ADT_Vector_get_elem(*v, (void **)&u2, user_pos) != OK)) {
                 destroy_2darray(data, IN_FILE_FIELDS);
-                free(user_tmp);
+                free(u1);
                 return st;
             }
-        }
 
-        /* Si no lo encuentra crea un usuario nuevo */
-        else { 
-            if((st = user_create(&user)) != OK) {
+            /* Crea un usuario nuevo para almacenar la copia */
+            if((st = user_create(&u3)) != OK) {
                 destroy_2darray(data, IN_FILE_FIELDS);
-                free(user_tmp);
+                free(u1);
                 return st;
             }
 
-            if((st = user_set_data(user, id, c, d))) {
+            /* Copia el contenido del usuario */
+            *u3 = *u2;
+
+            /* Asigna a la copia el nuevo monto */
+            if(amount > 0) u3->c += amount;
+            else if(amount < 0) u2->d -= amount;
+
+            /* Asigna la copia al vector en el lugar que estaba el usuario original */
+            if((st = ADT_Vector_set_elem(v, u3, user_pos)) != OK) {
                 destroy_2darray(data, IN_FILE_FIELDS);
-                free(user_tmp);
-                return st;
+                free(u1);
             }
 
-            /* Y lo agrega al vector */
-            if((st = ADT_Vector_add(v, user)) != OK){
+            free(u1);
+            free(u2);
+        }
+
+        /* Hubo un error distinto a no encontrar el usuario */
+        else if(st != ELEM_NOT_FOUND) {
+                destroy_2darray(data, IN_FILE_FIELDS);
+                return st;
+        }
+
+        else { 
+            /* Si no lo encuentra entonces lo agrega al vector */
+            if((st = ADT_Vector_add(v, u1)) != OK){
                 destroy_2darray(data, IN_FILE_FIELDS);
-                free(user_tmp);
                 return st;
             }
         }
-        clean_buffer(buffer);
-        clean_array(data);
+        clean_buffer(buffer); clean_array(data);
+        parsed_lines++;
     } /* End while */
 
-        
     destroy_2darray(data, IN_FILE_FIELDS);
-    free(user_tmp);
+    printf("%s%8ld\n", STR_MSG_END_PROCSS, parsed_lines);
 
     return OK;
 }
diff --git a/source/user.c b/source/user.c
@@ -12,31 +12,28 @@ status_t user_create(ADT_user_t **user)
     return OK;
 }
 
-status_t user_destroy(ADT_user_t **user)
+status_t user_dup(ADT_user_t *src, ADT_user_t *dst)
 {
-    if(user == NULL) return ERROR_NULL_POINTER;
+    status_t st;
 
-    free(*user);
-    *user = NULL;
+    if(src == NULL || dst == NULL) return ERROR_NULL_POINTER;
+
+    if((st = user_create(&dst)) != OK)
+        return st;
+
+    dst->id = src->id;
+    dst->c = src->c;
+    dst->d = src->d;
 
     return OK;
 }
 
-status_t user_set_data_from_str(ADT_user_t *user, char **data) 
+status_t user_destroy(ADT_user_t **user)
 {
-    char *endptr;
-    long amount;
-
-    if(data == NULL || user == NULL) return ERROR_NULL_POINTER;
-
-    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(user == NULL) return ERROR_NULL_POINTER;
 
-    if(amount > 0) user->c = amount;
-    else if(amount < 0) user->d = -amount; /* '-=' Para eliminar el menos    */
+    free(*user);
+    *user = NULL;
 
     return OK;
 }
diff --git a/source/utils.c b/source/utils.c
@@ -73,7 +73,7 @@ bool is_valid_card(char *card_no)
     if(card_no == NULL) return false;
     if(strlen(card_no) != CARD_NO_VALID_LEN) return false;
 
-    for(i = 0, k = 0; i < 4; i++) {
+    for(i = 0, k = 0, sum = 0; i < 4; i++) {
         for(j = 0; j < 4; j++) {
             arr[i][j] = (card_no[k++] - '0');
             if(j % 2) {
diff --git a/source/vector.c b/source/vector.c
@@ -57,55 +57,48 @@ status_t ADT_Vector_destroy(ADT_Vector_t **v)
 
 status_t ADT_Vector_set_elem(ADT_Vector_t **v, void *e, size_t pos)
 {
-    void ** aux;
-    size_t i, alloc_size;
+    /* 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;
+    /* 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;
-    }
+    /* /1* Cuenta cuanto tiene que alargar el arreglo p/ que entre el nuevo elemento *1/ */
+    /* 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;
-    }
+    /* 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);
-    }
+    /* if(pos >= (*v)->size) { */
+    /*     (*v)->size = (pos + 1); */
+    /* } */
 
     return OK;
 }
 
-void *ADT_Vector_get_elem(const ADT_Vector_t *v, void *e)
+status_t ADT_Vector_get_elem(const ADT_Vector_t *v, void **e, size_t pos)
 {
-    size_t i;
-
-    if(v == NULL || e == NULL) return NULL;
+    if(v == NULL || e == NULL) return ERROR_NULL_POINTER;
 
-    for(i = 0; i < v->size; i++) { 
-        if(v->comparator(e, v->a[i])) {
-            return v->a[i];
-        }
-    }
+    *e = v->a[pos];
 
-    return NULL;
+    return OK;
 }
 
 status_t ADT_Vector_get_elem_pos(const ADT_Vector_t *v, void *e, size_t *pos)