在Ruby中使用“猪拉丁语" [英] Using the 'pig latin language' in Ruby

查看:62
本文介绍了在Ruby中使用“猪拉丁语"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力寻找一种方法来验证这些方法,并且想知道是否有人知道执行此方法的基本方法?

I am struggling finding a way to verify these methods and was wondering if anyone knew a basic way to do this?

class PigLatinTest < MiniTest::Unit::TestCase

  def test_word_beginning_with_a
    assert_equal "appleay", PigLatin.translate("apple")
  end

  def test_other_word_beginning_e
    assert_equal "earay", PigLatin.translate("ear")
  end

  def test_word_beginning_with_p
    assert_equal "igpay", PigLatin.translate("pig")
  end

例如第一个可能是:

module PigLatin

  class Word
    def initialize(word)
        @word = word.to_s
    end
    # remember to use the .to_s method

    def translate(word)
        if word[0] == "a" || "e" || "o" || "u" || "i"
            word = word + "ay"
        elsif word[0] != "a" || "e" || "o" || "u" || "i"
            word = word-word[0]+"ay"
        end
    end
  end

  # you can add method here even outside of the class ...
end

------------在另一个文件中

------------in another file

module PigLatin

  class Word

    # remember to use the .to_s method

  end

  # you can add method here even outside of the class ...
end

推荐答案

您的translate方法无效.问题在这里:

Your translate method won't work. The problem is here:

if word[0] == "a" || "e" || "o" || "u" || "i"

elsif word[0] != "a" || "e" || "o" || "u" || "i"

您无法以这种方式进行比较,因为任何一方的右侧都不会像您认为的那样起作用.

You can't compare that way as the right side of either will not do what you think it will.

一些简单的检查将显示为什么出问题了:

Some simple checks will show why there's something wrong:

'abc'[0] == "a" || "e" || "o" || "u" || "i" # => true
'efg'[0] == "a" || "e" || "o" || "u" || "i" # => "e"
'opq'[0] == "a" || "e" || "o" || "u" || "i" # => "e"
'xyz'[0] == "a" || "e" || "o" || "u" || "i" # => "e"

'abc'[0] != "a" || "e" || "o" || "u" || "i" # => "e"
'efg'[0] != "a" || "e" || "o" || "u" || "i" # => true
'opq'[0] != "a" || "e" || "o" || "u" || "i" # => true
'xyz'[0] != "a" || "e" || "o" || "u" || "i" # => true

为什么这些错了?让我们看看发生了什么:

Why are those wrong? Let's look at what's happening:

当单词以'a'开头时,测试'a' == 'a'为真:

When the word starts with 'a', the test 'a' == 'a' is true:

'abc'[0] == "a" # => true

如果我们||(或")为true,则返回true,因为它是看到的第一个"true"值:

If we || ("or") true and something, we get true back because it was the first "true" value seen:

true || "e" # => true

如果第一个测试失败,则||导致对第二个测试进行评估,在您的代码中该代码为"e",不是测试,但是Ruby不知道,并认为这是一个测试.返回值"true",因此它成为表达式的结果:

If the first test failed, then || causes the second test to be evaluated, which in your code was "e", and wasn't a test, but Ruby didn't know that, and thought it was a "true" return value so it became the result of the expression:

false || "e" # => "e"

知道这一点的正确方法是:

Knowing that, a correct way to write this would be:

'abc'[0] == "a" || 'abc'[0] == "e" || 'abc'[0] == "o" || 'abc'[0] == "u" || 'abc'[0] == "i" # => true
'efg'[0] == "a" || 'efg'[0] == "e" || 'efg'[0] == "o" || 'efg'[0] == "u" || 'efg'[0] == "i" # => true
'opq'[0] == "a" || 'opq'[0] == "e" || 'opq'[0] == "o" || 'opq'[0] == "u" || 'opq'[0] == "i" # => true
'xyz'[0] == "a" || 'xyz'[0] == "e" || 'xyz'[0] == "o" || 'xyz'[0] == "u" || 'xyz'[0] == "i" # => false

'abc'[0] != "a" && 'abc'[0] != "e" && 'abc'[0] != "o" && 'abc'[0] != "u" && 'abc'[0] != "i" # => false
'efg'[0] != "a" && 'efg'[0] != "e" && 'efg'[0] != "o" && 'efg'[0] != "u" && 'efg'[0] != "i" # => false
'opq'[0] != "a" && 'opq'[0] != "e" && 'opq'[0] != "o" && 'opq'[0] != "u" && 'opq'[0] != "i" # => false
'xyz'[0] != "a" && 'xyz'[0] != "e" && 'xyz'[0] != "o" && 'xyz'[0] != "u" && 'xyz'[0] != "i" # => true

但是,这很快变得难以阅读和笨拙,因此需要一些更简洁的方法:

however, that rapidly becomes hard to read and unwieldy, so something more concise is needed:

%w[a e o u].include? 'abc'[0] # => true
%w[a e o u].include? 'efg'[0] # => true
%w[a e o u].include? 'opq'[0] # => true
%w[a e o u].include? 'xyz'[0] # => false

!%w[a e o u].include? 'abc'[0] # => false
!%w[a e o u].include? 'efg'[0] # => false
!%w[a e o u].include? 'opq'[0] # => false
!%w[a e o u].include? 'xyz'[0] # => true

这是有问题的;随着数组大小的增加,需要更多的循环才能与[0]值进行比较,从而不必要地降低了代码速度.正确编写的正则表达式可以消除该循环,从而使速度保持非常恒定:

There is a problem with this though; As the array size increases, more loops are required to compare to the [0] value, which slows the code unnecessarily. A regular expression, written correctly, can get rid of that looping so the speed stays very constant:

'abc'[0][/[aeou]/] # => "a"
'efg'[0][/[aeou]/] # => "e"
'opq'[0][/[aeou]/] # => "o"
'xyz'[0][/[aeou]/] # => nil

但是请注意,结果不是得到true/false,而是结果是由模式或nil匹配的字符.在Ruby中,只有nil和false被认为是false值,其他所有条件都为true,因此我们可以将它们分别转换为true,true,true,false,但是通过利用!运算符,我们可以使它更加清晰:

Notice though, that instead of getting true/false, the results are the character matched by the pattern or nil. In Ruby, only nil and false are considered false values, and everything else is true, so we can translate those into true, true, true, false respectively, but by taking advantage of the ! operator we can make it even more clear:

!!'abc'[0][/[aeou]/] # => true
!!'efg'[0][/[aeou]/] # => true
!!'opq'[0][/[aeou]/] # => true
!!'xyz'[0][/[aeou]/] # => false

似乎我们必须使用!!!来不"使用!=时想要的结果,但这不是必需的.单个!将执行相同的操作:

It might seem that we'd have to use !!! to "not" the results like we'd want when using !=, but that isn't necessary. A single ! will do the same thing:

!'abc'[0][/[aeou]/] # => false
!'efg'[0][/[aeou]/] # => false
!'opq'[0][/[aeou]/] # => false
!'xyz'[0][/[aeou]/] # => true

但是等等!还有更多!甚至可以通过删除字符串切片([0])并使用正则表达式锚将其略微改善.比较这两个及其基准:

But wait! There's more! Even that can be improved upon a slight amount by removing the string slice ([0]) and using a regex anchor. Compare these two, and their benchmark:

require 'fruity'

ALPHABET = ('a'..'z').to_a.join

compare do
  slice_it  { ALPHABET[0][/[aeou]/] }
  regex_it  { ALPHABET[/^[aeou]/] }
end
# >> Running each test 8192 times. Test will take about 1 second.
# >> regex_it is faster than slice_it by 39.99999999999999% ± 10.0%

因此,使用类似以下内容的

So, using something like:

'abc'[/^[aeou]/]  # => "a"
!'abc'[/^[aeou]/] # => false
!!'abc'[/^[aeou]/]  # => true

将快速而紧凑,让您测试一下字符串的开头.

will be fast and compact and let you test to see what a string starts with.

这篇关于在Ruby中使用“猪拉丁语"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆