Reputation: 87
I am creating a simple Magic-8 Ball program in Ruby. I want to make sure the user asks a question, so I've used the .include method in my conditional statements. I swore I was using it correctly, but I am getting errors when I run the program in the terminal.
I've tried using the .include method in different ways according to what I found on google, but nothing seems to be working.
puts "Please ask the Magic 8 Ball a YES/NO question:"
question = gets.chomp
puts "Please enter your name:"
name = gets.chomp
magic_8 = rand(6)
if question.include? "?" && magic_8 == 0
puts "\nIt is certain, #{name}."
elsif question.include? "?" && magic_8 == 1
puts "\nI'm not so sure, #{name}."
elsif question.include? "?" && magic_8 == 2
puts "\nI'll have to get back to you on that, #{name}."
elsif question.include? "?" && magic_8 == 3
puts "\nIt's not likely, #{name}."
elsif question.include? "?" && magic_8 == 4
puts "\nAbsolutely, #{name}!"
elsif question.include? "?" && magic_8 == 5
puts "\nDefinitely not, #{name}."
else
puts "Please enter a valid YES/NO question, #{name}."
end
I am expecting the program to output the conditional statements randomly as long as the user enters a question containing a "?".
Upvotes: 0
Views: 60
Reputation: 164679
/Users/schwern/tmp/test.rb:9:in `include?': no implicit conversion of false into String (TypeError)
from /Users/schwern/tmp/test.rb:9:in `<main>'
The problem is precedence. You can usually get away with not putting parenthesis around method arguments, but not this time.
question.include? "?" && magic_8 == 0
You're expecting this:
question.include?("?") && magic_8 == 0
But because &&
has a very high precedence, Ruby is interpreting this.
question.include?("?" && magic_8 == 0)
"?" && magic_8 == 0
is false
so that's question.include?(false)
which doesn't make sense.
So you need to be explicit about your parens. question.include?("?") && magic_8 == 0
.
We can also avoid the problem entirely by noticing that you're checking question.include?("?")
over and over again. This can be pulled into its own if/else block.
if question.include?("?")
case magic_8
when 0
puts "\nIt is certain, #{name}."
when 1
puts "\nI'm not so sure, #{name}."
when 2
puts "\nI'll have to get back to you on that, #{name}."
when 3
puts "\nIt's not likely, #{name}."
when 4
puts "\nAbsolutely, #{name}!"
when 5
puts "\nDefinitely not, #{name}."
end
else
puts "Please enter a valid YES/NO question, #{name}."
end
We only need to check if they've asked the question once. Then inside that if
we can use case/when, which is like a more convenient if/elsif, to check the 8 ball.
Upvotes: 1
Reputation: 10526
Use parentheses for arguments to method calls. You're confusing the interpreter without them.
if question.include?("?") && magic_8 == 0
puts "\nIt is certain, #{name}."
elsif question.include?("?") && magic_8 == 1
puts "\nI'm not so sure, #{name}."
elsif question.include?("?") && magic_8 == 2
puts "\nI'll have to get back to you on that, #{name}."
elsif question.include?("?") && magic_8 == 3
puts "\nIt's not likely, #{name}."
elsif question.include?("?") && magic_8 == 4
puts "\nAbsolutely, #{name}!"
elsif question.include?("?") && magic_8 == 5
puts "\nDefinitely not, #{name}."
else
puts "Please enter a valid YES/NO question, #{name}."
end
More here.
Upvotes: 0