7
\$\begingroup\$

I wrote Ruby code (copied below) but was told that the code does not compile (it does on my computer) and that it does not answer the question:

Create a class called Scrabble that implements a method called score that accepts one word as a parameter and returns the scrabble score associated with that word

The code compiles on my computer and provides the response that I believe was required. Can anyone point out issues with the code quality? I realize I did not write any unit tests for this code.

I could add more inline comments in the code (I added comments at the top of the class which I removed from the code I copied here).

class Scrabble

  attr_reader :word

  def initialize(word)
    @word = word
  end

  def score
    letters = word.upcase.split('')

    total = 0
    letters.each do |letter|
      total += letter_scores[letter]
    end

    total
  end

# scores for each letter
  def letter_scores
    {  "A"=>1, "B"=>3, "C"=>3, "D"=>2,
      "E"=>1, "F"=>4, "G"=>2, "H"=>4,
      "I"=>1, "J"=>8, "K"=>5, "L"=>1,
      "M"=>3, "N"=>1, "O"=>1, "P"=>3,
      "Q"=>10, "R"=>1, "S"=>1, "T"=>1,
      "U"=>1, "V"=>4, "W"=>4, "X"=>8,
      "Y"=>4, "Z"=>10
    }
  end
end


puts "Type in one word for scrabble scorer"
word = gets.chomp
puts "Scrabble score for " + word + " is " + Scrabble.new(word).score.to_s
\$\endgroup\$
1
  • 1
    \$\begingroup\$ one thing I noticed is that the requirement was for the method to take the word as an input (not for the class constructor to do so) \$\endgroup\$ Commented Aug 26, 2015 at 9:49

2 Answers 2

5
\$\begingroup\$

Some comments:

  • score method: With functional - instead of imperative - style, you'll get write more compact code.

  • You may use the abstraction Hash#values_at.

  • letter_scores is constant. It can be a class constant, then.

  • String interpolation: Use "#{var} = #{value}" style.

  • [edit] As you say, word should be an argument of score, not the class initializer.

I'd write:

class Scrabble
  LETTER_SCORES = {...}

  def score(word)
    scores = LETTER_SCORES.values_at(*word.upcase.chars)
    scores.compact.reduce(0, :+)
  end
end

scrabble = Scrabble.new
puts("Type in one word for scrabble scorer:")
word = gets.strip
puts("Scrabble score for #{word} is #{scrabble.score(word)}")
\$\endgroup\$
4
  • \$\begingroup\$ thank you - will accept soon if there are no better answers. +1. I agree on the strong interpolation comment. The expectation was to write imperative and not functional code (I agree with your statement on that end). Can you shed more light as to why using the class constant with values_at is preferable to the route I chose? I am curious to find out - thank you so much \$\endgroup\$ Commented Aug 26, 2015 at 7:21
  • 2
    \$\begingroup\$ No need to rush, give the other users some hours to answer (things go slowly in CR...). If you have a constant value in a class, it's more declarative to make it so. Also, it's only defined once. values_at is better here because that's exactly what you need, it saves you a loop. That imperative style you wrote is not idiomatic in Ruby. \$\endgroup\$
    – tokland
    Commented Aug 26, 2015 at 7:22
  • \$\begingroup\$ I would avoid assignement in the score function, just use a newline. \$\endgroup\$
    – Caridorc
    Commented Aug 26, 2015 at 12:36
  • \$\begingroup\$ I like to give names to intermediate values instead of writing big chains of expressions. In my experience, it helps when you come to the method some time after. Just a matter of taste, I guess. Not that it's a big expression here, indeed. \$\endgroup\$
    – tokland
    Commented Aug 26, 2015 at 12:41
1
\$\begingroup\$

The assignement text could be better, creating a class for just a single function is bad practice.

The constant SCRABBLE VALUES does not need to be inside such a class, a module level constant is ok, the Scrabble prefix is not needed.

I suggest a single function.

SCRABBLE_VALUES = {...}

def scrabble_value(word)
  # As in the other answer
end

You may refactor into a class as you add more functionality.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.