-1
\$\begingroup\$

Sorry if this has been answered to death—I'm working on a pig latin translator for Odin Project. The code below works fine for individual words, but when it receives two words ("eat pie"), the output is nil. Please let me know if I've left out any details. Thanks in advance for any suggestions.

def translate(word) 
consonants = ("b" || "c" || "d" || "f" || "g" || "h" || "j" || "k" || "l" || "m" || "n" || "p" || "q" || "r" || "s" || "t" || "v" || "w" || "x" || "y" || "z")
vowels = ("a" || "e" || "i" || "o" || "u")  

sentence = word.split(" ")
sentence.each do |word|

    if vowels.include?(word[0])
        pig = "#{word}ay" 

    elsif consonants.include?(word[0])
        c = word[0] 
        pig = word.delete(c).insert(-1, c) + "ay" 

    elsif vowels.include?(word[0]) && consonants.include?(word[0])
        c = word[0]
        pig = "#{word}ay" + word.delete(c).insert(-1, c) + "ay"

    elsif word[0].include?("c") && word[1] == "h"
        c = word[0..1]
        pig = word.delete(c).insert(-1, c) + "ay"

    elsif word[0] == "t" && word[1] == "h" && word[2] == "r"
        c = word[0..2]
        pig = word.delete(c).insert(-1, c) + "ay"

    elsif word[0..2].include?("sch")
        c = word[0..2]
        pig = word.delete(c).insert(-1, c) + "ay"

    elsif word[0..1].include?("qu")
        c = word[0..1]
        pig = word.delete(c).insert(-1, c) + "ay"

    elsif word.include?("squ")
        c = word[0..2]
        pig = word.delete(c).insert(-1, c) + "ay"

    end

    return pig
end 

end

\$\endgroup\$
0
\$\begingroup\$

Your biggest error is that you're not defining consonants and vowels as arrays of characters, but as a succession of single character joined by OR || conditions:

irb(main):046:0> consonants = ("b" || "c" || "d" || "f" || "g" || "h" || "j" || "k" || "l" || "m" || "n" || "p" || "q" || "r" || "s" || "t" || "v" || "w" || "x" || "y" || "z")
=> "b"
irb(main):047:0> vowels = ("a" || "e" || "i" || "o" || "u")
=> "a"

so 'b' and 'a' will be always true, then the rest of strings are ignored.
The real way to define arrays in ruby is with square braces and separated by comma, like ['a', 'b']. For your case, a simplified way to define array of strings is with %w, so you don't need to repeat quotes and comma symbols.

Another problem is, when you iterate your sentence array, at the end of the .each you're returning the first pig word created. Then you should create a pig array or concatenate resulting words to finally return pig out of the loop (this last option is what I'm going to use it).

  # these constants will be always the same, so I left them out of the method as
  # freezed constants, so there's no need to define them every time the method is 
  # invoked
  CONSONANTS = %w[b c d f g h j k l m n p q r s t v w x y z].freeze
  VOWELS = %w[a e i o u].freeze

  # defaulting to an empty string in case no strings are added
  def translate(sentence = '')
    # This is going to start as an empty string
    pig = ''
    # I think there's a naming misconception here. You're receiving a sentence
    # as parameter, which is composed of words. That's why I changed the
    # variable names.
    # Also, I'm calling `.split` without a parameter, as a space is the default.
    words = sentence.split
    words.each do |word|
      if VOWELS.include?(word[0])
        # To every string I'm concatenating the resulting word, which it has a
        # final space to be removed just before to return the result.
        pig << "#{word}ay "

      elsif CONSONANTS.include?(word[0])
        c = word[0]
        pig << word.delete(c).insert(-1, c) + 'ay '

      elsif VOWELS.include?(word[0]) && CONSONANTS.include?(word[0])
        c = word[0]
        pig << "#{word}ay" + word.delete(c).insert(-1, c) + 'ay '

      elsif word[0].include?('c') && word[1] == 'h'
        c = word[0..1]
        pig << word.delete(c).insert(-1, c) + 'ay '

      elsif word[0] == 't' && word[1] == 'h' && word[2] == 'r'
        c = word[0..2]
        pig << word.delete(c).insert(-1, c) + 'ay '

      elsif word[0..2].include?('sch')
        c = word[0..2]
        pig << word.delete(c).insert(-1, c) + 'ay '

      elsif word[0..1].include?('qu')
        c = word[0..1]
        pig << word.delete(c).insert(-1, c) + 'ay '

      elsif word.include?('squ')
        c = word[0..2]
        pig << word.delete(c).insert(-1, c) + 'ay '

      end
    end
    # No need to explicitly call `return` as the last value will be what will
    # return this method.
    # Finally calling `.rstrip` to remove trailing space in the final pig word
    pig.rstrip
  end

With this, no matter how many words you add it:

irb(main):045:0> translate 'eat a lot of pie'
=> "eatay aay otlay ofay iepay"

There's still some space to make improvements in this code, maybe moving part of the logic to new methods, but I leave that to you.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ When thinking of a Good Answer, respect that not all questions can or should be answered here. \$\endgroup\$ – greybeard Nov 27 '19 at 3:19
  • \$\begingroup\$ @greybeard oops, newbie mistake. 1st answer here in this S.E. site. I'll keep in mind those rules for the next one. Cheers \$\endgroup\$ – Alter Lagos Nov 27 '19 at 20:51
  • \$\begingroup\$ First, sorry for the errant post. Second, thanks for the help, @AlterLagos. That answers a few other basic questions I had in the process as well. \$\endgroup\$ – S.Faw Nov 28 '19 at 3:41

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