0

I'm trying to calculate what happens if the total score averages out above 100. I'm currently using a case statement to output the different scores. Would be the optimal solution to express the range above 100, allowing us to output 'A+++'.

def get_grade(score_1, score_2, score_3)
  total = (score_1 + score_2 + score_3)/3

  case total
  # What if the score is above 100? 
  # I want it to express 'A+++'
  when 90..100 then 'A'
  when 80..89 then 'B'
  when 70..79 then 'C'
  when 60..69 then 'D'
  else             'F'
  end
end

p get_grade(91, 97, 93) # => 'A'
p get_grade(52, 57, 51) # => 'D'
p get_grade(105, 106, 107) # => 'A++'
Louis Magnotti
  • 431
  • 1
  • 4
  • 19
  • 2
    I prefer @Nic's solution, but you could add either of the following lines to the case statement: `when 101..Float::INFINITY then 'A+++'` or `when 101..total then 'A+++'`. – Cary Swoveland Jul 29 '16 at 00:17

4 Answers4

6

That would be a typical case for the else clause. Why not rework your case statement to look like this, assuming each score argument is non-negative:

case total
  when 90..100 then 'A'
  when 80..89 then 'B'
  when 70..79 then 'C'
  when 60..69 then 'D'
  when 0..59 then 'F'
  else 'A+++'
end
Nic Nilov
  • 5,056
  • 2
  • 22
  • 37
  • I thought about that for sure; I just didn't know if there was another way to do so using INFINITY or anything else? Thanks! – Louis Magnotti Jul 28 '16 at 21:01
  • You could, but Ruby does not define a constant like `Fixnum::MAX`. Figuring out the actual value would be a little too involved, like [here](https://gist.github.com/pithyless/9738125) or [here](http://stackoverflow.com/a/736313/2116518). Therefore it's probably better to stick to a simple solution. – Nic Nilov Jul 28 '16 at 21:06
  • @NicNilov what about user passes one or more negative numbers as argument (which makes total < 0)? – marmeladze Jul 28 '16 at 21:14
4

You may combine methods and use comparisons

...
else
    if total > 100
        "A+++"
    else
         "F"
    end
end

If you want to play a little, you could change the case statement to:

(total > 100) ? "A+++" : "FFFFFFDCBAA"[(total/10).to_i]
Ruby Racer
  • 5,690
  • 1
  • 26
  • 43
2

You can provide a proc to the case to allow you to use an expression like > 100

def get_grade(score_1, score_2, score_3)
  total = (score_1 + score_2 + score_3)/3

  case total
  # What if the score is above 100? 
  # I want it to express 'A+++'
  when 90..100 then 'A'
  when 80..89 then 'B'
  when 70..79 then 'C'
  when 60..69 then 'D'
  when ->(n) { n > 100 } then 'A+++'
  else 'F'
  end
end
max pleaner
  • 26,189
  • 9
  • 66
  • 118
0

Here's a nifty solution using infinity:

first mentioned by @CarySwoveland

case total
  when 101..Float::INFINITY then 'A+++'
  when 90..100 then 'A'
  when 80..89 then 'B'
  when 70..79 then 'C'
  when 60..69 then 'D'
  else 'F'
end
Simply Beautiful Art
  • 1,284
  • 15
  • 16