typestar

grade_report.clj en Clojure

Promedia tres notas por estudiante, asigna una letra de calificación y cierra con un resumen del curso.

;; Term grade report for one small section.
(def roster
  [{:student "Alvarez" :scores [88 92 79]}
   {:student "Byrne"   :scores [71 65 74]}
   {:student "Chao"    :scores [95 98 91]}
   {:student "Dubois"  :scores [59 66 62]}
   {:student "Egan"    :scores [82 85 80]}
   {:student "Farkas"  :scores [48 55 51]}])

;; Dividing by a double keeps the result out of ratio arithmetic.
(defn average [xs]
  (if (seq xs)
    (/ (reduce + xs) (double (count xs)))
    0.0))

;; cond tries its test/result pairs in order and stops at the first
;; true test, so each band only needs its lower bound.
(defn letter [avg]
  (cond
    (>= avg 90) "A"
    (>= avg 80) "B"
    (>= avg 70) "C"
    (>= avg 60) "D"
    :else       "F"))

;; for is a comprehension, not a loop: it returns a new sequence.
(def graded
  (for [{:keys [student scores]} roster
        :let [avg (average scores)]]
    {:student student :avg avg :grade (letter avg)}))

(println (format "%-10s %6s %5s" "STUDENT" "AVG" "GRADE"))
(println (apply str (repeat 23 "-")))
(doseq [{:keys [student avg grade]} (sort-by :student graded)]
  (println (format "%-10s %6.1f %5s" student avg grade)))
(println (apply str (repeat 23 "-")))
(println (format "%-10s %6.1f" "CLASS" (average (map :avg graded))))
(println (format "%-10s %6d" "PASSING"
                 (count (remove #(= "F" (:grade %)) graded))))

Cómo funciona

  1. (/ (reduce + xs) (double (count xs))) promedia las notas, y double saca el resultado de la aritmética de razones.
  2. letter usa un cond que baja de (>= avg 90) hasta :else, así cada banda solo declara su cota inferior.
  3. (for [{:keys [student scores]} roster desarma cada entrada; :let [avg (average scores)] promedia una vez por alumno.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
39
Caracteres a escribir
1277
Tokens
275
Ritmo de tres estrellas
75 tpm

Al ritmo de tres estrellas de 75 tokens por minuto, este intento toma unos 220 segundos.

Escribe este fragmento

Paso 2 de 3 en Bis; paso 26 de 27 en Fundamentos del lenguaje.

← Anterior Siguiente →