grade_report.lisp in Lisp
Turns a list of students and test scores into per-student grades and a class summary.
;; grade_report.lisp: student averages, letter grades, and a class summary.
(defparameter *students*
'(("Ada" 92 88 95)
("Grace" 78 85 80)
("Alan" 65 72 70)
("Edsger" 88 91 84)
("Barbara" 55 61 58)))
(defun average (scores)
(/ (reduce #'+ scores) (float (length scores))))
(defun letter-grade (score)
(cond ((>= score 90) "A")
((>= score 80) "B")
((>= score 70) "C")
((>= score 60) "D")
(t "F")))
(defun report-row (record)
(let* ((name (first record))
(scores (rest record))
(mean (average scores)))
(format t "~10a ~{~5d~} ~9,2f ~a~%"
name scores mean (letter-grade mean))))
(format t "~10a ~15a ~9a ~a~%" "student" "scores" "average" "grade")
(dolist (record *students*)
(report-row record))
(let* ((means (mapcar (lambda (record) (average (rest record))) *students*))
(class-mean (/ (reduce #'+ means) (length means)))
(passing (count-if (lambda (mean) (>= mean 70)) means)))
(format t "~%class average ~,2f over ~d student~:p~%"
class-mean (length means))
(format t "passing at 70 or better: ~d of ~d~%" passing (length means))
(format t "highest average: ~,2f~%" (reduce #'max means)))
How it works
averagedivides by(float (length scores))so the result is not a ratio.letter-gradewalks acondfrom 90 down to the fallbacktclause.~10a ~{~5d~} ~9,2flines the columns up;count-ifcounts averages at 70 or better.
Keywords and builtins used here
conddefparameterdefundolistfirstfloatformatlambdalengthmapcarmaxreducerest
The run, in numbers
- Lines
- 37
- Characters to type
- 1097
- Tokens
- 262
- Three-star pace
- 75 tpm
At the three-star pace of 75 tokens a minute, this run takes about 210 seconds.
Step 2 of 3 in Encore, step 26 of 27 in Language basics.