2015-01-02 2 views
1

Ruby 및 Rails에서 가중치를 계산하는 데 문제가 있습니다. 예시 적 시나리오로서, 우리 학교의 한 반에 대해 가중 평균 성적 계산이 있다고 가정 해보십시오. 클래스 레벨 가중치가 각각 0.25, 0.50 및 0.25 인 테스트 "a", "b"및 "c"가 있습니다. Jenny의 점수는 마지막 테스트에서 면제 된 곳의 0.95, 0.85 및 nil입니다. 학생이 시험에서 면제되면, 가중치는 시험에 포함되어서는 안됩니다. 아래의 jenny_grade_scores가 ActiveRecord Object이고 TEST_WEIGHTS가 모델의 상수라고 가정합니다. 보다 효율적으로 사용하는 것보다 이것에 대한 가중 점수를 계산하는 방법은 무엇가중치 평균 등급 계산 - nil을 사용한 해시 반복

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

+0

0.6625가 분자이고 0.75 분모 = 0.883333 – UserDuser

+0

이다 없음 분모 제니 분모 0.75이어야하므로 시험 C 1 (= 0.25 + 0.5 + 0.25) –

+0

제니의 등급 점수 닐이다 없다. jenny_grade_scores [ "test_c"] 인 경우 jenny_test_weights [ "test_c_weight"] = 0.0을 참조하십시오. – UserDuser

답변

4

해야한다 ? 을 단순화 할 수있는 모든 관련 해시에 동일한 키에 테스트 키를 이름 바꾸기

  1. :

    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 
    

    각주 : 당신은 당신의 코드를 리팩토링 괜찮다면

    >> 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} 
    

    는 다음 사항을 고려 문제.

  2. nil은 float로 변환 될 때 0.0이됩니다.
  3. inject & reduce은 합계 또는 유사한 컬렉션 관련 작업을 우아하게 처리 할 수 ​​있습니다. 더 많은 관용적 인 루비 (Ruby)에 대해 익숙하지 않다면 &을 배우십시오.
  4. 벌칙이없는 가중치 계산을 위해 업데이트되었습니다.
+0

각주를 잘 찍었고 추한 코드를 리팩터링 할 수 있습니다. 감사합니다. 주입과 감소는 나에게 새로운 것이므로, 할 일이 있습니다. 내 질문에 대한 귀하의 의견에 대한 제 응답에서 언급 한 바와 같이 분모를 처리하는 더 좋은 방법이 있습니까? – UserDuser

+0

물론, 나는 벌칙이 적용되지 않은 체중 계산으로 업데이트했습니다. –

+0

아주 좋습니다. 고마워요. – UserDuser