Test Scores

May 24, 2016

We begin by creating test input:

(define scores '(("Alice" 84) ("Bob" 92) ("Alice" 93)
  ("Bob" 47) ("Charlie" 73) ("Dennis" 59) ("Eve" 91)
  ("Alice" 78) ("Charlie" 85) ("Eve" 68) ("Alice" 100)
  ("Charlie" 84) ("Dennis" 92) ("Eve" 85) ("Dennis" 83)
  ("Alice" 92) ("Bob" 68) ("Bob" 79) ("Dennis" 79)
  ("Alice" 84) ("Bob" 89) ("Charlie" 69) ("Charlie" 67)
  ("Charlie" 92) ("Dennis" 73) ("Eve" 79) ("Eve" 84)))

Processing occurs in two steps: First, we accumulate lists of scores for each student in an R6RS hash table. Second, we sort the scores, then take the average of the top five:

(define (score scores)
  (let ((ht (make-hashtable string-hash string=?)))
    (do ((scores scores (cdr scores)))
        ((null? scores))
      (hashtable-set! ht (caar scores)
        (cons (cadar scores)
              (hashtable-ref ht (caar scores) (list)))))
    (call-with-values
      (lambda () (hashtable-entries ht))
      (lambda (key value)
        (map (lambda (key value)
               (list key (/ (sum (take 5 (sort > value))) 5.)))
             (vector->list key) (vector->list value))))))

Here’s the output for our sample data:

> (score scores)
(("Dennis" 77.2)
  ("Eve" 81.4)
  ("Alice" 90.6)
  ("Charlie" 80.6)
  ("Bob" 75.0))

We used take and sum from the Standard Prelude. You can run the program at http://ideone.com/ux59n2, where you will see that Guile Scheme uses a different set of hashtable functions than standard R6RS, and takes the arguments to sort in a different order.

Pages: 1 2

One Response to “Test Scores”

  1. Rainer said

    In SQL for DB2:

    with students (id,name) as (values                             
    (1, 'A'),(2, 'B'),(3, 'C')),                                   
         scores (id,score,cnt) as                                  
    (select id, int(rand() * 100), 1                               
     from   students                                               
     union  all                                                    
     select id, int(rand() * 100), cnt + 1                         
     from   scores                                                 
     where  cnt < 10),                                             
         list (id,cnt,arr) as                                      
    (select id,cnt,cast(char(score) as varchar(50))                
     from   scores                                                 
     where  cnt = 1                                                
     union  all                                                    
     select s.id,s.cnt,trim(l.arr) concat ',' concat char(s.score) 
     from   list l                                                 
     inner  join scores s on l.id = s.id and l.cnt + 1 = s.cnt),   
         hits (id,score,rn) as                             
    (select id,score,row_number() over                     
                     (partition by id order by score desc) 
     from   scores),                                       
         average (id,val) as                               
    (select id, avg(score)                                 
     from   hits                                           
     where  rn <= 5                                        
     group  by id)                                         
    select a.id as student_id,                             
           a.val as average_score,                         
           l.arr as scores_list                            
    from   average a                                       
    inner  join list l                                     
    on     a.id = l.id and l.cnt = 10                      
    
    ==>
    
    STUDENT_ID   AVERAGE_SCORE   SCORES_LIST                   
             1              55   49,49,18,35,15,70,45,7,63,33  
             2              80   79,59,30,4,79,90,21,61,61,92  
             3              68   54,42,30,65,59,39,82,18,84,39 
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: