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

Weighted Average Grade Calculation - hash iteration with nil

我在计算 Ruby 和 Rails 中的加权比率时遇到问题。作为一个说明性场景,假设我们有一个 class 在学校的加权平均成绩计算。我有测试 "a"、"b" 和 "c",它们的 class 级权重分别为 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

将所有考试成绩转换为浮点数怎么样?

>> 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. nil 转换为 float 时变为 0.0.
  3. inject & reduce 可以优雅的做求和或者类似集合相关的操作。不仅如此,它更加地道 Ruby,如果您不熟悉它们,请尝试学习它们。
  4. 更新了非惩罚权重计算。