Forum: Ruby Trying to get "translator" to work

Posted by JD KF (joepoe)
on 2012-12-06 20:51
So, basically, I'm trying to get the below code to work properly for
"piglatin".  I have gotten it to work with mulitple words, if the word
starts with a vowel, if the word starts with a consonant, and if the
word starts with two consonants.  This was a hell of a lot of trial and
error getting to this point.

However, I am stuck and need a little help getting unstuck.  One thing
about "piglatin" is that I need to turn words like "quale" into
"alequay".  Also I need to have words like "square" to turn into
"aresquay".  AKA, if qu shows up somewhere, I need those letters (and
any that proceed it) to shift to the back and ad an +ay to the end.

The current code turns "quale" into "ualeqay" instead.


I have thought about this and really am unclear how to proceed about it.
The below code is the code I was talking about and made myself.  I
realize some things could probably be "cleaner" about it, but I'm just
starting to learn so it will do for now.

Anyhow, I would love to somehow get unstuck with this.

def translate(words)
  z=""
  vowels=%w(a e i o u)
  consonants=%w(b c d f g h j k l m n p q r s t v w x y z)
  words.gsub(/\w+/) do |word|
    #the word in a array
    z=word.scan(/\w/)
    #checks to see if first letter has a vowel
    contains_vowels=vowels & z.first.split(",")
    two_consonants=z[0..1] & consonants
    three_consonants = z[0..2] & consonants

    if(contains_vowels.size>=1)
          z.join("")+"ay"
    elsif(three_consonants.size==3)
          x=z.shift(3)
           z.join("")<<x.join("")+"ay"
    elsif(two_consonants.size==2)
           x=z.shift(2)
          z.join("")<<x.join("")+"ay"
    else
          x=z.shift
          z<<x+"ay"
          z.join("")
    end
  end
end
Posted by Joel Pearson (virtuoso)
on 2012-12-06 21:26
I'll have to have a think about the "qu" problem (one of the geniuses 
will probably beat me to it), but check this Regex out for extracting 
consonants: /a-z&&[^aeiou]]/i
Try it on www.rubular.com :)
Posted by JD KF (joepoe)
on 2012-12-06 22:40
On a side note, I tried the /a-z&&[^aeiou]]/i in rubular.com.  It 
basically said, "Forward slashes must be escaped".  I'm not sure it 
works.  I'm not familiar with using that website though.  I always just 
use IRB to test things.
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-12-06 22:45
(Received via mailing list)
On Thu, Dec 6, 2012 at 8:51 PM, JD KF <lists@ruby-forum.com> wrote:
> any that proceed it) to shift to the back and ad an +ay to the end.
> word = "square"
=> "square"
> first, second = word.match(/(.*qu)(.*)/).captures
=> ["squ", "are"]
> "#{second}#{first}ay"
=> "aresquay"

Jesus.
Posted by Joel Pearson (virtuoso)
on 2012-12-06 22:49
"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post 
#1088119:
> On Thu, Dec 6, 2012 at 8:51 PM, JD KF <lists@ruby-forum.com> wrote:
>> any that proceed it) to shift to the back and ad an +ay to the end.
>> word = "square"
> => "square"
>> first, second = word.match(/(.*qu)(.*)/).captures
> => ["squ", "are"]
>> "#{second}#{first}ay"
> => "aresquay"
>
> Jesus.

Way better than the shameful hack I ended up trying (writing another 
method to pass all the results through) :)
Posted by Joel Pearson (virtuoso)
on 2012-12-06 22:52
JD KF wrote in post #1088118:
> On a side note, I tried the /a-z&&[^aeiou]]/i in rubular.com.  It
> basically said, "Forward slashes must be escaped".  I'm not sure it
> works.  I'm not familiar with using that website though.  I always just
> use IRB to test things.

Here's a demo I made for you: http://www.rubular.com/r/7sZKl7CqJ1

The "i" after the last forward slash makes it case-insensitive. The same 
as adding (?i) at the beginning.
Posted by JD KF (joepoe)
on 2012-12-06 23:16
Maybe I am just bad at this, but I'm having a hard time figuring out how 
to implement what Jesus is saying into my if statements or code.

Maybe I'm just bad at this (well, I sort of am, but I am trying to 
learn).  Could someone maybe give me a nudge as to how to implement it 
into my code?

You don't have to give me the full answer, but some help would be great 
:/.
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-12-07 01:19
(Received via mailing list)
On Thu, Dec 6, 2012 at 11:16 PM, JD KF <lists@ruby-forum.com> wrote:
> Maybe I am just bad at this, but I'm having a hard time figuring out how
> to implement what Jesus is saying into my if statements or code.
>
> Maybe I'm just bad at this (well, I sort of am, but I am trying to
> learn).  Could someone maybe give me a nudge as to how to implement it
> into my code?
>
> You don't have to give me the full answer, but some help would be great
> :/.

I'm guessing the argument words is just a string, since you are
gsubbing it, so let's call it sentence.
What I'd do is split it first, then process each word separately,
applying the piglatin rules:

words = sentence.split(/\W/) # or some other variation
words.map! do |word|
 # apply piglatin rules to word
end

Jesus.
Posted by JD KF (joepoe)
on 2012-12-07 02:21
I have looked at what you are saying.  I'm having a hard time seeing how 
to work it into what I currently have.  But I am trying to implement 
what you are saying.

This is what I was thinking of doing.

Before the if, elsif statements, I put:

contains_qu=word.match(/(.*qu)(.*)/).captures
qu_length=contains_que.length

Then I have in the if conditions:

elsif(qu_length>=2)
   >>Code to swap things around
end

Problem is, the .captures will not work if the "word" does not have 
something containing qu.  It throws an error.  Anyone know a way around 
that?
Posted by Joel Pearson (virtuoso)
on 2012-12-07 08:19
contains_qu=word.match(/(.*qu)(.*)/).captures rescue contains_qu=nil
Posted by Harry Kakueki (Guest)
on 2012-12-07 14:41
(Received via mailing list)
On Fri, Dec 7, 2012 at 4:51 AM, JD KF <lists@ruby-forum.com> wrote:
> So, basically, I'm trying to get the below code to work properly for
> "piglatin".  I have gotten it to work with mulitple words, if the word
> starts with a vowel, if the word starts with a consonant, and if the
> word starts with two consonants.  This was a hell of a lot of trial and
> error getting to this point.


This is not a complete solution, but maybe you can modify the 'if'
statement to make the rules.
I am a bit rusty with pig latin.



def pig(w)
  arr = []
  (1...w.size).each do |a|
    if w[0...a] !~ /[aeiou]/ or (w[0...(a-1)] !~ /[aeiou]/ and
w[0...a] =~ /qu\z/)
      arr << w[a..-1]+w[0...a]+"ay"
    end
  end
  arr << w + "way" if w[0..0] =~ /[aeiou]/
  arr[-1]
end

words = [ "square", "quiet", "bird", 
"apple","require","start","strength"]

words.each{|f| p pig(f)}

## OUTPUT

"aresquay"
"ietquay"
"irdbay"
"appleway"
"equireray"
"artstay"
"engthstray"




Harry
Posted by Brian Candler (candlerb)
on 2012-12-07 15:48
I got lost trying to decode your logic for two consonants, three 
consonants etc, so here is a simple implementation of the rules from 
Wikipedia instead.

def translate(words)
  words.gsub(/\w+/) do |word|
    case word
    # In words that begin with consonant sounds, the initial consonant 
or
    # consonant cluster is moved to the end of the word, and "ay" is 
added.
    # Note that "qu" is treated as a consonant sound.
    when /^((b|c|d|f|g|h|j|k|l|m|n|p|qu|r|s|t|v|w|x|y|z)+)(.*)/i
      "#{$3}#{$1}ay"
    # In words that begin with vowel sounds or silent consonants, the 
initial
    # vowel is removed and the syllable "way" added to the end of the 
word
    # FIXME: silent consonants are not considered here.
    when /^[aeiou]+(.*)/i
      "#{$1}way"
    else
      word
    end
  end
end

puts translate("pig computer happy question another about quale square")

You may find the above rather terse for your liking, but it boils down 
to "if the word matches this pattern, then rebuild it using the captured 
parts like this". It's an example of the power and brevity of ruby :-)
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.