7.8.0.1
The Final Grade
#lang typed/racket |
(provide final-grade %) |
(define-type Projects (Pair Natural [Listof Assignment])) |
(define-type Assignment (Pair Exact-Rational Natural)) |
(define-type Presentations [Listof OK]) |
(define-type Panels [Listof OK]) |
(define-type LabBooks [Listof OK]) |
(define-type Percent Real) |
(define-type OK (U 'ok+ 'ok 'ok- 'zero)) |
(define-type Ten 10) |
(define (% {x : Real}) (/ x 100)) |
(define PROJECT (% 60)) |
(define PRESENTATION (% 17)) |
(define PANEL (% 17)) |
(define LAB (% 9)) |
(define FINAL (% 20)) |
(define ASSIGNMENTS (% 80)) |
[define ok+ (% 99)] |
[define ok (% 90)] |
[define ok- (% 77)] |
[define zero (% 42)] |
(: final-grade (Projects Presentations Panels LabBooks -> Percent)) |
(define (final-grade projects presentations panels labs) |
(+ (* PROJECT (project-grade projects)) |
(* PRESENTATION (presentation-grade presentations)) |
(* PANEL (panel-grade panels)) |
(* LAB (lab-book-grade labs)) |
(% 1))) |
(: project-grade (Projects -> Percent)) |
(define (project-grade projects) |
(match-define (cons final-code-walk assignments) projects) |
(+ (* FINAL (/ final-code-walk 10.0)) |
(* ASSIGNMENTS (assignment-grades assignments)))) |
(: assignment-grades (-> [Listof Assignment] Percent)) |
(define (assignment-grades grades) |
(define-values (student-score max-score) |
(for/fold : (values Real Real) |
([student-score 0.0][max-score 0]) |
([g : Assignment grades]) |
(match-define (cons student max) g) |
(values (+ student-score student) (+ max-score max)))) |
(/ student-score max-score)) |
(: okay-grades (-> [Listof OK] Percent)) |
(define (okay-grades oks) |
(/ (for/sum : Percent ((o : OK oks)) (grade-mapping o)) |
(length oks))) |
(: presentation-grade (Presentations -> Percent)) |
(define presentation-grade okay-grades) |
(: panel-grade (Panels -> Percent)) |
(define panel-grade okay-grades) |
(: lab-book-grade (LabBooks -> Percent)) |
(define lab-book-grade okay-grades) |
(: grade-mapping (OK -> Percent)) |
(define (grade-mapping o) |
(cond |
[(eq? o 'ok+) ok+] |
[(eq? o 'ok) ok] |
[(eq? o 'ok-) ok-] |
[(eq? o 'zero) zero] |
[else (error 'grade-mapping "unreachable code")])) |
(module+ test |
(require typed/rackunit) |
(: perfect-projects Projects) |
(: perfect-final-walk Ten) |
(define perfect-final-walk 10) |
(define perfect-projects (cons perfect-final-walk (list (cons 100 100)))) |
(define value-projects 1.0) |
(define perfect-presentations '(ok+ ok+)) |
(define value-presentations (/ (+ ok+ ok+) 2)) |
(define perfect-panels '(ok+ ok+ ok+)) |
(define value-panels (/ (+ ok+ ok+ ok+) 3)) |
(: perfect-labs LabBooks) |
(define perfect-labs '(ok+)) |
(define value-labs 1.0) |
(define perfect-grade |
(+ (* 3/5 value-projects) |
(* 17/100 value-presentations) |
(* 17/100 value-panels) |
(* 9/100 value-labs) |
(* 1/100))) |
(check-= |
(final-grade perfect-projects perfect-presentations perfect-panels perfect-labs) |
perfect-grade |
0.001)) |