ruby:当总和为 21 时,添加数字并打印 true
ruby: adding numbers and printing true when sums are 21
这是 rubeque.com 上给出的一个简单问题:编写一个方法,接受任意数量的整数并将它们加到 return 如果总和为 21,则为真。否则为假。它测试输入:
assert_equal twenty_one?(3, 4, 5, 6, 3), true
assert_equal twenty_one?(3, 11, 10), false
这是我目前的情况:
def twenty_one?(*nums)
nums.inject(&:+)
end
if twenty_one? == 21
puts true
else
false
end
但我收到错误消息:
RuntimeError: The value '21' does not equal 'true'.
我真的很困惑如何解决这个问题。是否可以将 if/else 语句放在方法中?抱歉,如果这个问题真的很基础。我是编程新手。
你需要把你的方法写成
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
这是一个小演示:-
require "minitest/autorun"
class Numerics
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
end
class TestNumerics < MiniTest::Test
def setup
@numeric = Numerics.new
end
def teardown
@numeric = nil
end
def test_twenty_one?
assert_equal @numeric.twenty_one?(3, 4, 5, 6, 3), true
assert_equal @numeric.twenty_one?(3, 11, 10), false
end
end
让我们运行 测试 :-
[arup@Ruby]$ ruby test/test_numerics.rb
Run options: --seed 61602
# Running:
.
Finished in 0.001332s, 750.9402 runs/s, 1501.8804 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
[arup@Ruby]$
在您的方法中,它返回 Fixnum
实例 21
,您试图将其与 true
进行比较。这就是你得到错误的原因。如果你查看 assert_equal
的来源,你会发现 2 个对象之间的比较是相同 class 的实例,否则它会抛出你得到的错误。
注意: 你当然也可以把这个 nums.inject(&:+)
写成 nums.inject(:+)
因为 Ruby 允许这种自由 #reduce/#inject
方法特别开箱即用。
更新
给出了一个设计这个问题的好主意。想法是把方法放在模块里面,然后include它来测试它的方法:
require "minitest/autorun"
module Numerics
def twenty_one?(*nums)
nums.inject(:+) == 21
end
end
class TestNumerics < MiniTest::Test
include Numerics
def test_twenty_one?
assert_equal twenty_one?(3, 4, 5, 6, 3), true
assert_equal twenty_one?(3, 11, 10), false
end
end
现在如果我运行它:
arup_ruby$ ruby test/test_numerics.rb
Run options: --seed 1223
# Running:
.
Finished in 0.001067s, 937.2071 runs/s, 1874.4142 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
arup_ruby$
好主意!
Arup 的回答很棒。我建议让它更通用一些。
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
def compare_value_with_sum_of_nums?(value, *nums)
nums.inject(&:+) == value
end
我真的很不会取名字。这让我觉得将您的方法名称与元编程和 gem humanize 结合起来会很酷。然后,您可以拥有动态方法名称,并从方法名称中推断出总和应达到的值。所以你可以进行任何比较,比如
MyAwesomeGem.three_thousand_and_twenty_four?(3000, 20, 4)
建造会很有趣!
:)
这是 rubeque.com 上给出的一个简单问题:编写一个方法,接受任意数量的整数并将它们加到 return 如果总和为 21,则为真。否则为假。它测试输入:
assert_equal twenty_one?(3, 4, 5, 6, 3), true
assert_equal twenty_one?(3, 11, 10), false
这是我目前的情况:
def twenty_one?(*nums)
nums.inject(&:+)
end
if twenty_one? == 21
puts true
else
false
end
但我收到错误消息:
RuntimeError: The value '21' does not equal 'true'.
我真的很困惑如何解决这个问题。是否可以将 if/else 语句放在方法中?抱歉,如果这个问题真的很基础。我是编程新手。
你需要把你的方法写成
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
这是一个小演示:-
require "minitest/autorun"
class Numerics
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
end
class TestNumerics < MiniTest::Test
def setup
@numeric = Numerics.new
end
def teardown
@numeric = nil
end
def test_twenty_one?
assert_equal @numeric.twenty_one?(3, 4, 5, 6, 3), true
assert_equal @numeric.twenty_one?(3, 11, 10), false
end
end
让我们运行 测试 :-
[arup@Ruby]$ ruby test/test_numerics.rb
Run options: --seed 61602
# Running:
.
Finished in 0.001332s, 750.9402 runs/s, 1501.8804 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
[arup@Ruby]$
在您的方法中,它返回 Fixnum
实例 21
,您试图将其与 true
进行比较。这就是你得到错误的原因。如果你查看 assert_equal
的来源,你会发现 2 个对象之间的比较是相同 class 的实例,否则它会抛出你得到的错误。
注意: 你当然也可以把这个 nums.inject(&:+)
写成 nums.inject(:+)
因为 Ruby 允许这种自由 #reduce/#inject
方法特别开箱即用。
更新
require "minitest/autorun"
module Numerics
def twenty_one?(*nums)
nums.inject(:+) == 21
end
end
class TestNumerics < MiniTest::Test
include Numerics
def test_twenty_one?
assert_equal twenty_one?(3, 4, 5, 6, 3), true
assert_equal twenty_one?(3, 11, 10), false
end
end
现在如果我运行它:
arup_ruby$ ruby test/test_numerics.rb
Run options: --seed 1223
# Running:
.
Finished in 0.001067s, 937.2071 runs/s, 1874.4142 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
arup_ruby$
好主意!
Arup 的回答很棒。我建议让它更通用一些。
def twenty_one?(*nums)
nums.inject(&:+) == 21
end
def compare_value_with_sum_of_nums?(value, *nums)
nums.inject(&:+) == value
end
我真的很不会取名字。这让我觉得将您的方法名称与元编程和 gem humanize 结合起来会很酷。然后,您可以拥有动态方法名称,并从方法名称中推断出总和应达到的值。所以你可以进行任何比较,比如
MyAwesomeGem.three_thousand_and_twenty_four?(3000, 20, 4)
建造会很有趣!
:)