marcelogarberoglio / PI

Para realizar consultas
5 stars 0 forks source link

EJ COURSE #277

Open santiagoBassi opened 1 year ago

santiagoBassi commented 1 year ago

Hola Marcelo, buenas tardes. Te molesto para preguntarte por el ejercicio que charlamos hoy en clase. Como no tenia el enunciado interprete un poco diferente la consigna y en consecuencia modifique algunas lineas del test. Pero el problema es que por algun motivo parece que la funcion addStudentRec parece no estar insertando a "BRAULITO" y a "CARLOS" te adjunto el codigo y la salida. Si ves varios printf y puts es porque estaba intentando encontrar el error. Gracias!

#include "courseADT.h"
#include "string.h"
#include "ctype.h"
#include <stdio.h>

typedef struct node{
    char * name;
    struct node * tail;
}TNode;

typedef TNode * TList;

typedef struct subject{
    size_t code;
    char * name;
    TList first;

}TSubject;

typedef struct courseCDT{
    TSubject * courses;
    size_t qty;
    int nextSubject;
    TList nextStudent;
}courseCDT;

void printList(TList list){
    if(list==NULL)
        return;
    puts(list->name);
    printList(list->tail);
}

/* Crea un curso con qty materias
 ** Al principio todas las materias tienen el nombre vacio (NO NULL)
 */
courseADT newCourseADT(size_t qty){
    courseADT new=malloc(sizeof(courseCDT));
    new->qty=qty;
    new->courses=malloc(qty*sizeof(TSubject));
    for(int i=0; i<qty;i++){
        new->courses[i].name=calloc(1,sizeof(char));
        new->courses[i].first=NULL;
    }
    return new;
}
//--------------------------------------------------------------------------

static void freeStudentRec(TList list){
    if(list==NULL)
        return ;
    freeStudentRec(list->tail);
    free(list);
}

/*Libera la memoria reservada por el TAD*/
void freeCourseADT (courseADT course){
    for(int i=0; i<course->qty;i++){
        freeStudentRec(course->courses[i].first);
        free(course->courses[i].name);
    }
    free(course->courses);
    free(course);

}
//-----------------------------------------------------------------------------

static int valid(const char * name, size_t * len){
    int i;
    int flag=1;
    for(i=0; name[i]!='\0' && flag; i++){
        flag=(isalpha(name[i]) || isspace(name[i]));
    }

    if(name[i]=='\0')
        *len=i;
    return flag;
}

 /*  Si el codigo de la materia es valido , cambia el nombre de la misma
 **  Retorna 1 si el codigo de la materia es valido, cero si no.
 */
int setSubject(courseADT course, size_t subject , char * name){
    size_t lenSub;
    if(subject<=0 || !valid(name, &lenSub)){
        return 0;
    }
    int found=0;
    int i;
    for(i=0;i<course->qty &&  course->courses[i].name[0]!='\0' && !found;i++){
        found=strcmp(name,course->courses[i].name)==0;
    }
    if(!found){
        course->courses[i].name=realloc(course->courses[i].name, sizeof(char)*(lenSub+1));
        strcpy(course->courses[i].name, name);
        course->courses[i].code=subject;
        return 1;
    }
    return 0;
}
//-----------------------------------------------------------------------------------------------

static TList addStudentRec(TList list, const char * name, int * inserted){
    int c;
    if(list==NULL || (c=strcmp(list->name, name))>0){

        TList aux=malloc(sizeof(TNode));
        aux->name=name;
        aux->tail=list;
        *inserted+=1;
        return aux;
    }
    if(c<0){
        list->tail=addStudentRec(list->tail,name,inserted);
    }
    return list;
}

/* Agrega un alumno a una materia especificada por el codigo
 * Si el codigo es invalido o el alumno ya esta en la materia
 * retorna 0 , si no retorna 1
 */
int addStudent(courseADT course , size_t subject , char * student){
    if(subject<=0){
        return 0;
    }
    int found=0;
    int i;
    for(i=0; i<course->qty && course->courses[i].name[0]!='\0' && !found;i++){
        found=subject==course->courses[i].code;
    }
    if(found){
        int inserted=0;
        printf("Voy a agregar a %s\n",student);
        course->courses[i].first=addStudentRec(course->courses[i].first,student,&inserted);
        return inserted;
    }
    return 0;
}

/* Agrega un alumno a todas las materias en las que no estaba
 * ya inscripto
 * retorna la cantidad de materias a las que fue agregado
 */
int addStudentToAll(courseADT course, char * student){
    int inserted=0;
    int i;
    for(i=0;i<course->qty &&  course->courses[i].name[0]!='\0';i++){
        course->courses[i].first=addStudentRec(course->courses[i].first,student,&inserted);
    }
    return inserted;

}

/* Permite iterar sobre todas las materias , ubicandose en la primer
 materia */
void toBegin(courseADT course){
    course->nextSubject=0;
}

/* Retorna una copia del nombre de la siguiente materia
 * Si no hay mas materias para recorrer retorna NULL
 */
char * next(courseADT course){
    if(course->nextSubject==course->qty)
        return NULL;
    char *aux=malloc(sizeof(char)*(strlen(course->courses[course->nextSubject].name)+1));
    strcpy(aux,course->courses[course->nextSubject].name);
    course->nextSubject++;
    return aux;
}

/* Se ubica al principio de una materia, en base al codigo de la misma
 * Si el codigo es valido retorna una copia del nombre de la materia
 * Si el codigo es invalido retorna NULL
 * Al pedir los alumnos, lo hace en orden alfabetico
 */
char * toBeginForSubject(courseADT course , size_t subject){
    int found=0;
    int i;
    char * ans=NULL;
    for(i=0;i<course->qty &&  course->courses[i].name[0]!='\0' && !found;i++){
        found= subject==course->courses[i].code;
    }
    i--;
    if(found){
        ans=malloc(sizeof(char)*(strlen(course->courses[i].name)+1));
        strcpy(ans,course->courses[i].name);
        course->nextStudent=course->courses[i].first;
    }
    return ans;

}
/* Retorna 1 si hay algun alumno mas por recorrer en la materia*/
int hasNextForSubject(courseADT course){
    return course->nextStudent!=NULL;
}

/* Retorna uan copia del nobmre del siguiente alumno de la materia,
 * por orden alfabetico.
 * Si no hay mas alumnos en la materia aborta la ejecucion
 */
char * nextForSubject(courseADT course){
    printList(course->courses[0].first);
    puts("espacio Loco");
    if(!hasNextForSubject(course))
        exit(1);
    char * ans=malloc(sizeof(char)*(strlen(course->nextStudent->name)+1));
    strcpy(ans,course->nextStudent->name);
    course->nextStudent=course->nextStudent->tail;

    return ans; 
}

Cuando ejecuto una funcion que imprime la lista me dice: ANA, JUAN

Gracias!

marcelogarberoglio commented 1 year ago

Lo que está muy raro es la forma en que ubicás la materia. Si subject es el código, entonces es la materia que está en

course->courses[subject-1]

ya que los códigos van de 1 a qty inclusive

porque a la función de agregar un estudiante no le veo fallas, asumiendo que el test está pasando strings constante, sinó tenés que cambiar esta línea aux->name=name; por aux->name=strcpy(malloc(strlen(name)+1), name);

Fijate de arreglar esas dos cosas y ver si anda

santiagoBassi commented 1 year ago

Ah, entonces el test esta mal, porque hay codigos que son: 10, 20 ,30,50, 110. Y qty es 10. Igual con eso que me decis me quedo tranquilo, porque me parecia muy raro que este fallando el add, y en ese caso estaba al horno. Gracias!

marcelogarberoglio commented 1 year ago

Hay variantes del ejercicio, la que hoy planteamos era que cada materia tenía un código entre 1 y qty, para hacerlo con vector de listas, algo que estuvimos haciendo durante la cursada. Si fuera que los códigos son 10, 20, 110, etc y además hay que poder recorrer o iterar en forma ordenada por código, entonces tendría que ser una lista de materias, y por cada materia una lista de alumnos, pero no vimos lista de listas este cuatrimestre, sólo está el socialADT como ejercicio adicional u optativo en la guía.