在clojure中的向量的变构列表中映射每个元素(mapping over each element in a destructured list of vectors in clojure)

编程入门 行业动态 更新时间:2024-10-24 10:22:01
在clojure中的向量的变构列表中映射每个元素(mapping over each element in a destructured list of vectors in clojure)

我是一名大学教练,试图获得一点Clojure乐趣并同时计算我的成绩。 我列出了所有学生的数字及其相应的成绩,如下所示:

(def grades-1 (let [s18129 [100 70 85 71 85] s18121 [80 75 85 81 85] r18131 [75 60 80 56 75] ...]) ;; r before the number is shorthand for repeater ;; and not important to this question

我希望对这些成绩进行调整,以使这些向量中的第一,第二,第三,第四和第五等级分别加权到10%,20%,15%,25%和30%。 为了帮助我完成这项任务,我创建了一个辅助函数:

(defn percentify "adjust raw score to weighted percentile" [raw percentile] (* (/ raw 100) percentile))

我想创建另一个将映射成绩列表的函数,并根据其位置,以向量中每个元素的特定权重将percentify函数应用于每个学生的成绩。 这就是我现在正在使用的东西,但我不能让它在repl中工作。 我认为这与我如何构建我的类数据有关,或者我对使用println感到困惑。

(defn finalize [grades-list] (let [[[student] [a b c d e]] grades-list] (println (percentify a 10.0) (percentify b 20.0) (percentify c 15.0) (percentify d 25.0) (percentify e 30.0))))

然后我想调用这个函数以可读的形式返回最终成绩和学生数。 有人可以帮忙让我走上正轨吗?

I am a university instructor trying to have a little Clojure fun and calculate my grades at the same time. I have made a list of all of my students numbers with their corresponding grades into something that looks like this:

(def grades-1 (let [s18129 [100 70 85 71 85] s18121 [80 75 85 81 85] r18131 [75 60 80 56 75] ...]) ;; r before the number is shorthand for repeater ;; and not important to this question

I would like the grades to be adusted so that the first, second, third, fourth and fifth grades in these vectors are weighted to 10%, 20%, 15%, 25% and 30%, respectively. To help me accomplish this task, I created a helper function:

(defn percentify "adjust raw score to weighted percentile" [raw percentile] (* (/ raw 100) percentile))

I want to create another function that will map over the grades list and apply the percentify function to each student's grades at a specfic weight for each element in the vector, based on its position. This is what I am working with right now, but I can't make it work in the repl. I think it has to do with how I've structured my class data or perhaps, I am confused about the use of println.

(defn finalize [grades-list] (let [[[student] [a b c d e]] grades-list] (println (percentify a 10.0) (percentify b 20.0) (percentify c 15.0) (percentify d 25.0) (percentify e 30.0))))

I then want to call on this function to return the final grades with the numbers of the students in a readable form. Could someone please help to put me on the right track?

最满意答案

数据自然是从学生编号(字符串)到成绩矢量的地图:

(def grades-1 {"s18129" [100 70 85 71 85] "s18121" [80 75 85 81 85] "r18131" [75 60 80 56 75]})

...以及要应用于上述的权重向量:

(def grade-weights [10 20 15 25 30])

...从学生编号到最终成绩的地图。 我们怎么能这个因素呢?

根据给定weights向量计算平均值的函数是

(fn [grades] (/ (reduce + 0.0 (map * weights grades)) (reduce + weights)))

......在哪里

0.0的初始值强制使用浮点运算和 权重不需要加起来为1.0或100或特别是任何数字。 包括缩放。

以下将a-map每个值转换为该值的函数f :

(fn [f a-map] (into {} (map (fn [[k v]] [k (f v)]) a-map)))

因此,从等级向量和加权向量的映射提供最终成绩的地图的功能是......

(defn av-grades [gt weights] (let [weight-av (fn [grades] (/ (reduce + 0.0 (map * weights grades)) (reduce + weights))) convert-map (fn [f a-map] (into {} (map (fn [[k v]] [k (f v)]) a-map)))] (convert-map weight-av gt)))

而且,果然,......

=>(av-grades grades-1 grade-weights) {"r18131" 68.0, "s18121" 81.5, "s18129" 80.0}

The data is naturally a map from student-number (a string) to a vector of grades:

(def grades-1 {"s18129" [100 70 85 71 85] "s18121" [80 75 85 81 85] "r18131" [75 60 80 56 75]})

... and a vector of weights to be applied to the above:

(def grade-weights [10 20 15 25 30])

... turning out a map from student-number to final grade. How can we factor this?

A function to calculate the average according to a given weights vector is

(fn [grades] (/ (reduce + 0.0 (map * weights grades)) (reduce + weights)))

... where

the initial value of 0.0 forces the use of floating point arithmetic and the weights need not add up to 1.0 or 100 or any number in particular. Scaling is included.

The following converts each value of a-map into a function f of that value:

(fn [f a-map] (into {} (map (fn [[k v]] [k (f v)]) a-map)))

So a function to deliver a map of final grades from a map of grade vectors and a weighting vector is ...

(defn av-grades [gt weights] (let [weight-av (fn [grades] (/ (reduce + 0.0 (map * weights grades)) (reduce + weights))) convert-map (fn [f a-map] (into {} (map (fn [[k v]] [k (f v)]) a-map)))] (convert-map weight-av gt)))

And, sure enough, ...

=>(av-grades grades-1 grade-weights) {"r18131" 68.0, "s18121" 81.5, "s18129" 80.0}

更多推荐

本文发布于:2023-08-02 19:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1379550.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:向量   元素   列表中   clojure   mapping

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!