2014-11-05 27 views
-2

我在努力尋找一種方法來驗證這些方法,並想知道是否有人知道一個基本的方法來做到這一點?在Ruby中使用'pig latin language'

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 

------------在另一個文件

module PigLatin 

    class Word 

    # remember to use the .to_s method 

    end 

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

您需要爲''PigLatin'模塊添加一個'translate'方法。我不知道'Word'類與這個有什麼關係,除了你可能希望移動那裏的功能並使'translate'使用那個類。這個問題太廣泛,無法進一步回答。 – meagar 2014-11-05 19:05:41

+0

Iway ouldway agreeway ithway @eagarmay atthay ethay estionquay isway ootay oadbray。 – 2014-11-05 20:53:21

回答

2

translate方法不會工作。問題就在這裏:

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

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

您可以這種方式無法比擬的任右邊不會做你認爲它會。

一些簡單的檢查將說明爲什麼有些不對勁:

'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 

爲什麼這些錯誤?讓我們來看看發生了什麼:

當這個詞與「A」開始,測試'a' == 'a'是正確的:

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

如果我們||(「或」)真實的東西,我們得到真正的回來,因爲它在第一個「真」值看出:

true || "e" # => true 

如果首次測試失敗,則||導致第二測試進行評估,這在你的代碼是"e",而不是一個測試,但沒紅寶石」不知道,並認爲這是一個「tr UE」返回值,以便它成爲表達式的結果:

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

知道了,寫這個正確的方法是:

'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 

然而,迅速變得難以閱讀和笨重,所以需要更簡潔的東西:

%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]值進行比較,這會不必要地降低代碼的速度。正則表達式,正確書寫,可以擺脫循環,這樣的速度保持非常穩定:

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

注意雖然,而不是讓真/假,結果是由圖案或無匹配的字符。在Ruby中,只有nil和false被認爲是假的值,其他的都是真的,所以我們可以分別將它們轉換爲true,true,true和false,但是通過利用!運算符,我們可以更加清楚:

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

可能看起來我們不得不使用!!!「不」的結果一樣,我們會使用!=時想要的,但不是必要的。一個!將做同樣的事情:

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

但是等等!還有更多!即使通過刪除字符串片段([0])並使用正則表達式錨點,也可以稍微提高這一點。比較這兩種,它們的基準:

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% 

因此,使用這樣的:

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

將是快速和緊湊,讓你測試一下,看看有什麼字符串開始。