2013-05-20 46 views
5

Noob to Ruby here。通過一些練習,並打了一堵牆。使用一系列等級計算字母等級

練習:計算一系列牌號

的信等級創建一個接受測試成績的陣列的方法get_grade。數組中的每個分數應該在0到100之間,其中100是最高分數。

計算平均得分並將字母等級返回爲字符串,即'A','B','C','D','E'或'F'。

我回頭率錯誤

avg.rb:1: syntax error, unexpected tLBRACK, expecting ')' 
def get_grade([100,90,80]) 
      ^
avg.rb:1: syntax error, unexpected ')', expecting $end 

這裏是我到目前爲止所。我想堅持下面的方法或.join,因爲我正在嘗試使用我們在課堂上學習的方法。所以總結,注入等不一定會有幫助。而且,我對提出請求的具體性事先表示歉意:)我確信有一種更好的方式可以減少代碼,但我只是想通過這種方式來學習。

def get_grade([100,90,80]) 
     get_grade = (array[0] + array[1] + array[2]).to_i/array.length.to_i 
    case get_grade 
     when 90..100 
     "A" 
     when 80..90 
     "B" 
     when 70..80 
     "C" 
     when 60..70 
     "D" 
     when 0..60 
     "F" 
     else 
    "Error" 
     end 
    end 

    puts get_grade([100,90,80]) 

回答

7

你不能只是隨意傾倒文字像[100,90,80]數組到函數定義的參數列表。通過函數體來看,我覺得你的意思是接受一個單一的參數array

def get_grade(array) 
    grade = (array[0].to_i + array[1].to_i + array[2].to_i)/array.length 
    case grade 
    # unchanged 
    end 
end 
+0

另外,上檔次的計算可以略有改善:'array.inject(:+)/ array.size'。 –

+1

@BenjaminTan我知道,我很樂意;但引用這個問題:「我想堅持下面的方法或加入,因爲我正在嘗試使用我們在課堂上學習的方法,所以總結,注入等不一定有幫助。」 – michaelb958

+0

是的,但我真的無法抗拒。 :) –

0

感謝您今天的幫助!這就是我最終做的,使它不只有3個參數。我使用了數組#每種方法。我想有一個更優雅的解決方案,但它的工作!自上午10點開始工作,非常感謝幫助!

def get_grade(array) 
    sum = 0 
    array.each do |element| 
    sum += element 
    end 
    average = sum/array.length 
    if average >= 90 
     grade = "A" 
    elsif average >= 80 
     grade = "B" 
    elsif average >= 70 
    grade = "C" 
    elsif average >= 60 
    grade = "D" 
    elsif average >= 0 
    grade = "F" 
    else 
    "Error" 
    end 
end 

puts get_grade([70,80,80,90,100]) 
puts get_grade([100,80,90,11,20]) 
puts get_grade([30,20,10,60,75]) 
+0

期待進一步瞭解.inject,因爲我看到它在幾個主板上被列爲此問題的解決方案!任何關於它的鏈接都會被讚賞,因爲我在ruby-docs方法文檔中找不到它。 – ideahed

+0

'inject'是'Enumerable'混搭的一部分,你可以在這裏看到這個文檔http://ruby-doc.org/core-2.0/Enumerable.html – Abizern

0

請記住,最高分數是100(並且可以假定min是0)。

def get_grade(array) 
sum = 0 
array.each do |x| 
    sum += x 
end 

average = sum/array.length 

if average > 100 
    print "Grades must be no more than 100!" 
elsif average >= 90 
    grade = "A" 
elsif average >= 80 
    grade = "B" 
elsif average >= 70 
    grade = "C" 
elsif average >= 60 
    grade = "D" 
elsif average >=0 
    grade = "F" 
else 
    print "Grades must be no less than 0!" 
end 
grade 
    end 

puts get_grade([100,90,80]) == "A" 
puts get_grade([98,90,80]) == "B" 
puts get_grade([80,80,80]) == "B" 
puts get_grade([55,45,35]) == "F" 
puts get_grade([101,100,104]) 
puts get_grade([-2,-3,-4]) 
0

添加了一個proc,以便即使用戶輸入超過100的分數,它也不會被計算爲平均值。 還將switch語句重構爲每行一行。讓我知道這是否有幫助。祝你好運。

def get_grade array 
    scores_under_100 = Proc.new {|score| score <= 100 && score > 0} 
    scores = array.select(&scores_under_100) 
    average = scores.inject(:+)/scores.size 

    case average 
     when 90..100 then puts "A." 
     when 80..89 then puts "B." 
     when 70..79 then puts "C." 
     when 60..69 then puts "D." 
     else puts "F." 
    end 
    end 

puts get_grade([100, 100, 90, 67, 85, 200, 290, 299, 299]) 
+0

@ michaelb958知道你想遠離對象方法,但是我認爲這仍然是一個可以傳遞儘可能多分數的可靠方法。 – MartianE

1

一個簡潔更換大case聲明,爲了好玩:

def letter_grade(score) # assumes that score is between 0 and 100 (not 0-1) 
    %w[F F F F F F D C B A][ (score/10.0).floor ] || 'A' # handles grades >=100 
end 

或者,更細的粒度:

def letter_grade(score) # score is between 0 and 100 (not 0-1) 
    grades = %w[F F F F F F F F F F F F F F F F F F D- D D+ C- C C+ B- B B+ A- A A+ A+] 
    grades[ (3.0*score/10).floor ] 
end