/* The LearningOnline Network with CAPA * CAPA wrapper code * $Id: caparesponse.c,v 1.20 2005/12/20 19:59:52 albertel Exp $ * * Copyright Michigan State University Board of Trustees * * This file is part of the LearningOnline Network with CAPA (LON-CAPA). * * LON-CAPA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * LON-CAPA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with LON-CAPA; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * /home/httpd/html/adm/gpl.txt * * http://www.lon-capa.org/ */ #include #include PointsList_t * parse_pts_list (char *pts_list) { PointsList_t *new=NULL, *end=NULL, *beforeend=NULL, *rlist=NULL; char *idx_pts=pts_list; int done=0; /*fprintf(stderr,"ids %s\n",id_list); fprintf(stderr,"pts %s\n",pts_list);*/ while (!done && pts_list) { int idx; /*fprintf(stderr,"pts; %s\n",idx_pts);*/ new=gen_ptslist_str(idx_pts); if (!new) break; if (!rlist) { rlist=new; } if (end) { end->pts_next=new; idx=end->pts_idx; } else { idx=-1; } end=new; while (end) { idx++; end->pts_idx=idx; /*fprintf(stderr,"end is:%d:%d:%s:%d\n",idx,end->pts_idx,end->pts_str, end->pts_next);*/ beforeend=end; end=end->pts_next; } end=beforeend; idx_pts=strchr(idx_pts,';'); if (idx_pts) { idx_pts++; } else { done=1; } } return rlist; } int caparesponse_capa_check_answer(char *response,char *correct, int type,int tol_type,double tolerance, int sig_lbound,int sig_ubound, char *ans_fmt, char *unit_str, int calc, char *id_list, char *pts_list, char *rndseed, char** reterror) { long result,seed1,seed2; Problem_t p; char *error=NULL,filename[FILE_NAME_LENGTH]; FILE *fp; /* need to initialize unit parser*/ *reterror=NULL; sprintf(filename,"/home/httpd/html/res/adm/includes/capa.units"); if ((fp=fopen(filename,"r"))==NULL) { /* printf("Error: can't open %s\n",filename);*/ return (-1); } u_getunit(fp); fclose(fp); /* need to setup random generator (FIXME) should only do this if it hasn't been yet*/ phrtsd(rndseed,&seed1,&seed2); setall(seed1,seed2); /* assign_id_list and assign_pts_list exist in capaGrammerDef.y */ p.id_list=NULL; p.pts_list=NULL; if (type == ANSWER_IS_FORMULA) { p.id_list=id_list; p.pts_list=parse_pts_list(pts_list); // if ( p.id_list == NULL || p.pts_list == NULL) { // return BAD_FORMULA; // } } p.ans_type = type; p.answer = correct; p.tol_type = tol_type; p.tolerance = tolerance; p.sig_lbound = sig_lbound; p.sig_ubound = sig_ubound; if (ans_fmt != NULL ) { strncpy(p.ans_fmt,ans_fmt,ANSWER_STRING_LENG-1); } if (unit_str != NULL && unit_str[0]!='\0') { strncpy(p.unit_str,unit_str,ANSWER_STRING_LENG-1); //p.ans_unit = u_parse_unit(unit_str); p.ans_unit = parse_unit_expr(unit_str); p.ans_unit = process_utree(p.ans_unit); //print_unit_t(p.ans_unit); } else { p.unit_str[0]='\0'; p.ans_unit=NULL; } p.calc = calc; result=capa_check_answer(&p,response,&error); *reterror=error; // Caller is expected to free reterror // if (error!=NULL) {free(error);} return result; } int caparesponse_get_real_response (char* unit_str, char* answer, double* scaled) { //double caparesponse_get_real_response (char* unit_str, char* answer) { int input_len,all_alphabet,idx,outcome=-1,result; double n_part,scale=1.0,given,target; char input[ANSWER_STRING_LENG],filename[FILE_NAME_LENGTH], tmp_unit_str[ANSWER_STRING_LENG]; Unit_t *ans_unit; long seed1,seed2; FILE *fp; sprintf(filename,"/home/httpd/html/res/adm/includes/capa.units"); if ((fp=fopen(filename,"r"))==NULL) { /* printf("Error: can't open %s\n",filename);*/ return (-1); } u_getunit(fp); fclose(fp); if (unit_str != NULL && unit_str[0]!='\0') { ans_unit = parse_unit_expr(unit_str); ans_unit = process_utree(ans_unit); } else { ans_unit=NULL; } input_len = strlen(answer); all_alphabet = 1; for(idx=0;idx 0 ) { if( outcome > 1 ) { /* with both num and unit parts or only unit part */ if( ans_unit != NULL ) { result = check_correct_unit(tmp_unit_str,ans_unit,&scale); } else { /* what to do when no unit is specified but student entered a unit? */ result = UNIT_NOTNEEDED; } } else { if( ans_unit != NULL ) { result = NO_UNIT; } } if( (result != NO_UNIT) && (!check_for_unit_fail(result)) && ( result != UNIT_NOTNEEDED) ) { given = n_part * scale; *scaled=given; /* convert the given answer into proper scale for units */ } /* end if unit check */ } else { /* user entered a lphabet, but no number */ result = WANTED_NUMERIC; } return result; } /* Testing harnass int main(void) { int result=0; char *reterror=NULL; result= caparesponse_capa_check_answer("10^3","1000", ANSWER_IS_FORMULA, TOL_ABSOLUTE,1E-3, 3,5,NULL,NULL, CALC_UNFORMATED, "","4", "rndseed", &reterror); fprintf(stderr,"result %d\nreterror: %s\n",result,reterror); } */