File:  [LON-CAPA] / capa / capa51 / pProj / checkunits.c
Revision 1.2: download - view: text, annotated - select for diffs
Fri Jun 30 21:36:16 2000 UTC (24 years, 4 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- gave everyone the GPL header

/* harness to test the unit engine out
   Copyright (C) 1992-2000 Michigan State University

   The CAPA system is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CAPA system 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the CAPA system; see the file COPYING.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* 
   Units is checked against real or integer answers, 
   for string and choice answers, units is not checked 
   
          UNIT_NOTNEEDED  ==> user entered some units and answer did not need one
          NO_UNIT         ==> 
          UNIT_FAIL
   
   ans_type must be either ANSWER_IS_INTEGER or ANSWER_IS_FLOAT
   or else, skip or return UNIT_NOTNEEDED
   if unit_p is NULL, then UNIT_NOTNEEDED
   
   answer must contains at least one digit 
   
   
*/

/*   


#define    EXACT_ANS           1
#define    APPROX_ANS          2 
#define    SIG_FAIL            3
#define    UNIT_FAIL           4
#define    NO_UNIT             5
#define    UNIT_OK             6
#define    INCORRECT           7
#define    UNIT_NOTNEEDED      8
#define    ANS_CNT_NOT_MATCH   9
  /*  called from capaCommon.c */
/*                      */
/*  UNIT_FAIL           */
/*  NO_UNIT             */
/*  result: UNIT_OK correct   */
/*                            */
 */

/* capa_check_units() only works under ANSWER_IS_INTEGER or ANSWER_IS_FLOAT */
int
capa_check_units( ans, u_p ) char *ans;Unit_t *u_p;
{
  input_len = strlen(ans);
  all_alphabet = 1;
  for(idx=0;idx<input_len;idx++) {
    if( isdigit(ans[idx]) ) {
      all_alphabet = 0;
    }
  }
  
  if( !all_alphabet ) { /* contains at least a digit char */
    outcome = split_num_unit(ans,&n_part,num_str,unit_str);
    /* num_str is used in calc_sig() for sig fig */
    /* n_part is used together with scale from check_correct_answer() */
    /* unit_str is used later as input to check_correct_unit() */
    if( outcome > 1 ) {  /* with both num and unit parts or only unit part */
    
      if( u_p != NULL ) {
          result = check_correct_unit(unit_str,u_p,&scale);
          /* result could be UNIT_OK, UNIT_FAIL */
          
          
      } else { /* no unit is specified but student entered an units? */
          
          result = UNIT_NOTNEEDED;
          
      }

    } else { /* outcome = 0 empty string, 1 a number without units */
      if( u_p != NULL ) {
          
          result = NO_UNIT; /* units required */
          
      } else { 
          result = INCORRECT, /* proceed to check numerical value */
      }
    }
    /* at this point, result could be one of UNIT_OK, UNIT_FAIL, UNIT_NOTNEEDED, and NO_UNIT */
    
    sig = calc_sig( num_str );
    
  } else {   /* contains all non-digit  char */
      result = INCORRECT;  /* the students may enter an units but not containing any number */
      
  }
  return (result);
}














int
capa_check_allunits(p,answers,cnt) Problem_t *p; char **answers; int cnt;
{
  int     type; 
  char   *correct;
  char    input[ANSWER_STRING_LENG], unit_str[UNIT_STRING_LENG];
  int     tol_type, calc_type;
  double  tol, n_part; 
  int     sig_l; 
  int     sig_u;
  char   *fmt;
  int     choice[SIXTY_FOUR], ii, idx, corr_len, input_len;
  int     result = INCORRECT, sig, outcome, all_alphabet;
  char    fmted[FORMAT_STRING_LENG];
  double  given, target, ratio, fmted_target, target_u, target_l, scale=1.0;
  double  delta;
  
  type       = p->ans_type;
  correct    = p->answer;
  tol_type   = p->tol_type;
  tol        = p->tolerance;
  sig_l      = p->sig_lbound;
  sig_u      = p->sig_ubound;
  fmt        = p->ans_fmt;
  calc_type  = p->calc;
  unit_str[0]= 0;
  
  if( (cnt != p->ans_cnt) ) { return (ANS_CNT_NOT_MATCH); }
  switch(type) {
    case ANSWER_IS_INTEGER:
    case ANSWER_IS_FLOAT:
          {
            input_len = strlen(ans);
            all_alphabet = 1;
            for(idx=0;idx<input_len;idx++) {
              if( isdigit(ans[idx]) ) {
                all_alphabet = 0;
              }
            }
            if( !all_alphabet ) {  /* answer string is not all alphabets */
              outcome = split_num_unit(ans,&n_part,num_str,unit_str);
              if( outcome > 1 ) {  /* with both num and unit parts or only unit part */
                if( u_p != NULL ) {
                  result = check_correct_unit(unit_str,u_p,&scale);
                } else { /* what to do when no unit is specified but student entered a
                unit? */
                  result = UNIT_NOTNEEDED;
                }
              } else {
                if( u_p != NULL ) {
                  result = NO_UNIT;
                }
              }
  
  idx = 1;  ai = p->ans_list;
       while( (idx<cnt) && ( (result == EXACT_ANS) || (result == APPROX_ANS) ) ) {
         result =  capa_check_ans(ai,answers[idx]);
         ai = ai->ans_next; idx++;
       }
  if(num_answer==2)  printf("Answer:->%s [%s,%s] %s, ",p->answer,lower,upper,
			    p->unit_str); 
      else  printf("Answer:->%s, ",lower);
  switch(p->ans_type) {
       case ANSWER_IS_INTEGER:   printf(" INTEGER,");
        break;
       case ANSWER_IS_FLOAT: 
        printf(" FLOAT format=%s, SIG=[%d,%d],",
          p->ans_fmt,p->sig_lbound,p->sig_ubound );
        break;
       case ANSWER_IS_STRING_CI: printf(" STRING C.I.,"); break;
       case ANSWER_IS_STRING_CS: printf(" STRING C.S.,"); break;
       case ANSWER_IS_CHOICE:    printf(" CHOICE,");      break;
   }
   printf(" WEIGHT=%d, TRIES=%d\n", p->weight,p->tries); fflush(stdout);
   if(p->ans_unit != NULL) {
        print_unit_t(p->ans_unit);  fflush(stdout);
   }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>