加权平均等级计算 - 使用nil进行哈希迭代

时间:2015-01-02 17:36:11

标签: ruby-on-rails ruby hash

我在Ruby和Rails中计算加权比率时遇到了麻烦。作为一个说明性的场景,假设我们有一个学校班级的加权平均成绩计算。我有测试“a”,“b”和“c”,它们的类级权重分别为0.25,0.50和0.25。珍妮的分数分别为0.95,0.85和零,她在最后一次考试中获得豁免。当学生免于考试时,加权不应计入其中。考虑下面的jenny_grade_scores是ActiveRecord对象,TEST_WEIGHTS是模型中的常量。

jenny_grade_scores = { "test_a" => 0.95, "test_b" => 0.85, "test_c" => nil }

TEST_WEIGHTS = { "test_a_weight" => 0.25, "test_b_weight" => 0.50, "test_c_weight" => 0.25 }

计算加权分数的有效方法是什么,而不是使用:

jenny_test_weights = TEST_WEIGHTS #initialize a student test weight variable and adjust if test score is nil
jenny_test_weights["test_a_weight"] = 0.0 if jenny_grade_scores["test_a"].nil?
jenny_test_weights["test_b_weight"] = 0.0 if jenny_grade_scores["test_b"].nil?
jenny_test_weights["test_c_weight"] = 0.0 if jenny_grade_scores["test_c"].nil?


numerator = (jenny_grade_scores["test_a"] * jenny_test_weights["test_a_weight"] +jenny_grade_scores["test_b"] * jenny_test_weights["test_b_weight"] + jenny_grade_scores["test_c"] * jenny_test_weights["test_c_weight"]) 

denominator = (jenny_test_weights["test_a_weight"] + jenny_test_weights["test_b_weight"] + jenny_test_weights["test_c_weight"])

final_score = numerator / denominator

在此示例中,结果应为0.88333333

1 个答案:

答案 0 :(得分:4)

如何将所有考试成绩转换为浮动?

>> jenny_grade_scores.inject({}) { |hash, array| hash[array[0]] = array[1].to_f; hash }           
=> {"test_a"=>0.95, "test_b"=>0.85, "test_c"=>0.0}

如果您不介意重构代码,请考虑以下事项:

WEIGHTS = { a: 0.25, b: 0.5, c: 0.25 }

grades = { a: 0.95, b: 0.85 , c: nil }

SUM_OF_WEIGHTS = WEIGHTS.inject(0) do |sum, (test, weight)|
  sum += grades[test].nil? ? 0 : weight
end # => 0.75

weighted_score = grades.inject(0) do |w, (test, score)|
  w += (score.to_f * WEIGHTS[test])
end # => 0.6625

final_score = weighted_score / SUM_OF_WEIGHTS # => 0.8833333333333333

脚注:

  1. 将测试密钥重命名为所有相关哈希中的相同密钥可以简化问题。
  2. 转换为float时,
  3. nil变为0.0。
  4. inject& reduce可以优雅地进行求和或类似的集合相关操作。更多的是惯用的Ruby,试试&如果你不熟悉它,请学习它们。
  5. 针对非惩罚体重计算进行了更新。