--- loncom/homework/caparesponse/caparesponse.c 2000/10/02 22:15:37 1.3 +++ loncom/homework/caparesponse/caparesponse.c 2005/12/01 22:34:10 1.19 @@ -1,44 +1,206 @@ +/* The LearningOnline Network with CAPA + * CAPA wrapper code + * $Id: caparesponse.c,v 1.19 2005/12/01 22:34:10 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) + int calc, char *id_list, char *pts_list, + char *rndseed, char** reterror) + { - int result; + long result,seed1,seed2; Problem_t p; char *error=NULL,filename[FILE_NAME_LENGTH]; FILE *fp; - printf("hi in caparesponse\n"); - - /*need to initialize unit parser*/ - sprintf(filename,"/home/httpd/html/res/adm/include/capa.units"); + /* 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; - strncpy(p.ans_fmt,ans_fmt,ANSWER_STRING_LENG-1); - strncpy(p.unit_str,unit_str,ANSWER_STRING_LENG-1); - p.ans_unit = u_parse_unit(unit_str); + + 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; - /* assign_id_list and assign_pts_list exist in capaGrammerDef.y */ - p.id_list=NULL; - p.pts_list=NULL; - result=capa_check_answer(&p,response,&error); + *reterror=error; + // Caller is expected to free reterror + // if (error!=NULL) {free(error);} - 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,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 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); +} +*/