How to check if an array includes either X or Y - ruby

My assignment is to check whether a given input by the user contains the letters "c" or "s". I managed with one but, I simply don't know the correct way to write that.
I know that the problem is "s" || "c".
print 'What can we do for you?'
user_input = gets.chomp
user_input.downcase!
if user_input.empty?
puts 'Well you will have to write something...!'
elsif user_input.include? 's' || 'c'
puts "We got ourselves some 's's and some 'c's"
user_input.gsub!(/s/, 'th')
user_input.tr!('c', 's')
puts "The Daffy version, #{user_input}!"
else
print "Nope, no 's' or 'c' found"
end

simply
elsif user_input.include?("s") || user_input.include?("c")
or something like
%w(s c).any? { |command| user_input.include? command }

This is the perfect example of where regular expressions are fine:
user_input =~ /[sc]/

or:
(user_input.split('') & %w(s c)).any?

You can use Regexp
user_input[/s|c/]

No regexp:
user_input.count('sc') > 0

Related

How to use .include? to capture multiple options resulting in same operation

I am writing a simple calculator that asks the user what calculation she wants to perform with a choice between '+', '-', '*' and '/'.
The code works when I separate each option with ||. However, I would prefer to use .include? to avoid repetition.
while play_again != "N"
puts "Enter a first number:"
first_num = gets.chomp.to_i
puts "Enter a second number:"
second_num = gets.chomp.to_i
puts "Which operation would you like to perform? '+', '-', 'x', '/'"
operator = gets.chomp
if operator == "+" || operator == "-" || operator == "x" || operator
== "/"
puts calculator(first_num, second_num, operator)
else
puts "That wasn't a valid selection."
end
puts "Do you want to calculate something else? (Y/N)"
play_again = gets.chomp
end
I tried to rewrite the line starting with if operator with if operator.include?(%w[+ - X /].to_s) but this doesn't capture the user input properly and always puts " That wasn't a valid selection."
In this way
if %w(+ - * /).include?(operator)
a shorter way for this one
if ["+", "-", "*", "/"].include?(operator)
This makes sense, don't you think? You're checking that the operator is included in some options. In this case the options are four strings, the symbols for the four basic mathematical operations.
A case when control structure lets you specify multiple conditionals. Sounds hard, is actually easy:
puts case operator
when '+', '-', 'x', '/' then calculator(first_num, second_num, operator)
else "That wasn't a valid selection."
end

How to re-prompt and re-use a user's input

I was trying to re-prompt a user's input and reuse it. Here's the code sample:
print "Please put your string here!"
user_input = gets.chomp
user_input.downcase!
if user_input.include? "s"
user_input.gsub!(/s/,"th")
elsif user_input.include? ""
user_input = gets.chomp
puts "You didn't enter anything!Please type in something."
user_input = gets.chomp
else
print "no \"S\" in the string"
end
puts "transformed string: #{user_input}!"
My elsif will let the user know that their input was not acceptable, but was not effective in re-using their input to start from the beginning. How am I supposed to do it? Should I use a while or for loop?
Hope this solves your problem :)
while true
print 'Please put your string here!'
user_input = gets.strip.downcase
case user_input
when ''
next
when /s/
user_input.gsub!(/s/, "th")
puts "transformed string: #{user_input}!"
break
else
puts "no \"S\" in the string"
break
end
end
You can have a loop at the beginning to continuously ask for input until it's valid.
while user_input.include? "" #not sure what this condition is meant to be, but I took it from your if block
user_input = gets.chomp
user_input.downcase!
end
This will continuously ask for input until user_input.include? "" returns false. This way, you don't have to validate input later.
However, I'm not sure what you are trying to do here. If you want to re-prompt when the input is empty, you can just use the condition user_input == "".
EDIT: Here's the doc for String.include?. I tried running .include? "" and I get true for both empty and non-empty input. This means that this will always evaluate to true.
user_input = nil
loop do
print "Please put your string here!"
user_input = gets.chomp
break if user_input.length>0
end
user_input.downcase!
if user_input.include? "s"
user_input.gsub!(/s/,"th")
else
puts "no \"S\" in the string"
end
puts "transformed string: #{user_input}!"

How to display modified string?

I am creating a Daffy Duck speech converter (Very simple. Straight from CodeCademy) and I am having an issue with displaying the modified entry from the user.
Code:
puts "What would you like to convert to Daffy Duck language?"
user_input = gets.chomp
user_input.downcase!
if user_input.include? "s"
user_input.gsub!(/s/, "th")
print #{user_input}
else puts "I couldn't find any 's' in your entry. Please try again."
end
It will change any 's' in your entry to a 'th', therefore, making it sound like a Daffy Duck once read aloud. When I enter it into the interpreter, it will not display the modified string. It will just display the original entry by the user.
EDIT:
Thanks to the users below, the code is fixed, and I added a notice to the user with converted text. Thanks guys!
A # outside a string starts a comment, so #{user_input} is ignored, i.e.
print #{user_input}
is equivalent to
print
You might wonder why a single print outputs the original input. This is because without arguments print will print $_. That's a global variable which is set by gets:
user_input = gets.chomp # assume we enter "foo"
user_input #=> "foo"
$_ #=> "foo\n"
Everything works as expected if you pass a string literal:
print "#{user_input}"
or simply
print user_input
Note that gsub! returns nil if no substitutions were performed, so you can actually use it in your if statement:
if user_input.gsub!(/s/, "th")
print user_input
else
puts "I couldn't find any 's' in your entry. Please try again."
end
You just need to add double quotes around the string interpolation. Otherwise your code was just returning the input.
puts "What would you like to convert to Daffy Duck language?"
user_input = gets.chomp
user_input.downcase!
if user_input.include? "s"
user_input.gsub!(/s/, "th")
print "#{user_input}"
else
puts "I couldn't find any 's' in your entry. Please try again."
end
You don't even need interpolation, actually. print user_input works. Notice how StackOverflow was even syntax highlighting your code as a comment. :)

"Bug" in if statement parameters Learn Ruby The Hard Way

On line 7 of http://learnrubythehardway.org/book/ex35.html, there is a comment stating there is a bug.
When this program runs and you choose a number which contains, neither a "0" nor a "1" it will say it's not a number. How do I get it to detect all numbers?
Here is the code:
def gold_room
puts "This room is full of gold. How much do you take?"
print "> "
choice = $stdin.gets.chomp
# this line has a bug, so fix it
if choice.include?("0") || choice.include?("1")
how_much = choice.to_i
else
dead("Man, learn to type a number.")
end
if how_much < 50
puts "Nice, you're not greedy, you win!"
exit(0)
else
dead("You greedy bastard!")
end
end
You can use regular expression here. \d means any digit, + means one or more times, =~ is a pattern match operator, so:
if choice =~ /\d+/
how_much = choice.to_i
else
dead("Man, learn to type a number.")
end

Ruby - Adding more than one includes on an if statement

I have the following code which works fine
if user_input.include? "s"
user_input.gsub!(/s/ "th")
else
print "Nothing to change"
end
But when I want to add another include like so it does not recognize the elsif How do I add these includes together?
if user_input.include? "s"
user_input.gsub!(/s/ "th")
elsif user_input.include? "cee"
user_input.gsub!(/cee/ "th")
else
print "Nothing to change"
end
Since gsub! returns nil if nothing changed, your can write your example just like this:
unless user_input.gsub!(/s|cee/ "th")
print "Nothing to change"
end
This is because of flow of execution of if else statement.
If condition in 'if' matches it will not execute 'elseif' block..
if user_input.include?('s') or user_input.include?('cee')
user_input.gsub!(/s/,"th").gsub!(/cee/,"th")
else
print "Nothing to change"
end
Your code show the error :
SyntaxError: unexpected ')', expecting keyword_end
You forget the commas in gsub
if user_input.include? "s"
user_input.gsub!(/s/, "th")
elsif user_input.include? "cee"
user_input.gsub!(/cee/, "th")
else
print "Nothing to change"
end
Edit :
If you want to make both replacement, you need to change to :
old_value = user_input
if user_input.include? "s"
user_input.gsub!(/s/, "th")
end
if user_input.include? "cee"
user_input.gsub!(/cee/, "th")
end
if user_input == old8value
print "Nothing to change"
end
Once the first if is matched, the rest are skipped.
For your particular use case, I would suggest that you use a single gsub like so:
regexp = /s|cee/
if string.match(regexp)
string.gsub!(regexp, "th")
else
"Nothing to gsub!"
end

Resources