Case statement don't work - ruby

I'm learning Ruby from "Programming Ruby, The Pragmatic Programmers(2nd, 2005)" and I'm stuck in the Case statement chapter.
So i copy-paste some code in my version from book:
def kind
puts "Type year and I'll tell you genre: "
ask = gets.chomp
kind = case ask
when 1850..1889 then "Blues"
when 1890..1909 then "Ragtime"
when 1910..1929 then "New Orleans Jazz"
when 1930..1939 then "Swing"
when 1940..1950 then "Bebop"
else "Jazz"
end
puts "You typed year #{ask}. Genre of music in that period is
#{kind}."
end
kind
Hence, whatever year I'm put, output is "Jazz"...What am I working incorrectly?

gets.chomp returns a string, and you are comparing that with integers.
You can inspect ask after you assigned it:
ask = gets.chomp
p ask
When you run the script and enter a number (e.g. 1940), you should see "1940" printed in the terminal. The quotes around the number show you that the variable holds a string, not a number. (FYI don't use puts here, since it won't show the quotes.)
As mudasobwa wrote in his comment, the way to fix this is to cast the input to a number before you compare it:
ask = gets.chomp.to_i
If you add p ask again, you should now see that only the number is printed to the terminal, without any " surrounding it. This shows you that the variable holds an integer.

Related

How can I stop Ruby if/elsif statement from looping?

I am teaching myself Ruby by making a small game in order to test out how I feel about the language. My code was going rather smoothly until I encountered a problem in which the first decision of the game loops instead of progressing forwards.
This code is what I have been using for a short part in the Exposition of my game.
def getup_or_sleep?
puts"Cole";
puts"----";
puts"Will you get up or go back to sleep?";
decision = gets
if decision == "sleep";
puts"Cole";
puts"----";
puts"You decide to go back sleep. It is far too early.";
elsif decision == "get up";
Exposition.stretch
else;
Exposition.getup_or_sleep?
end
This is the expected result I was hoping to achieve:
Cole
Will you get up or go back to sleep?
If player chooses 'sleep'
1)Cole
You decide to go back to sleep, it is far too early.
*I plan to make a new method to direct the user to, but I first want to fix this issue.
**if player chooses 'get up'
->>> to stretch method which is inside of the same class.
I'm new to coding so I may be confused on a few things. Thanks in advance! =)
Your method calls itself recursively because it all conditions fail, and it always falls back to the else branch.
This happens because gets reads input from the user and returns the input including the invisible newline character that is added when the user hits the enter key. But your conditions do not include such new line characters.
A common Ruby idiom is to call gets.chomp to get user input, where the chomp removes the newline character from the input.
Just change this line decision = gets to
decision = gets.chomp
to fix your issue.
Apart from that, your code isn't following Ruby idioms, for example, Ruby does not require a ; at the end of a line, or you usually add a whitespace between a method name and its argument, like in puts "Cole". Therefore, I suggest formatting your code like this:
def getup_or_sleep?
puts 'Cole'
puts '----'
puts 'Will you get up or go back to sleep?'
decision = gets.chomp
if decision == 'sleep'
puts 'Cole'
puts '----'
puts 'You decide to go back sleep. It is far too early.'
elsif decision == 'get up'
Exposition.stretch
else
Exposition.getup_or_sleep?
end
end
Or with a case block and some duplication extracted into a method:
def greeting
puts 'Cole'
puts '----'
end
def getup_or_sleep?
greeting
puts 'Will you get up or go back to sleep?'
case gets.chomp
when 'sleep'
greeting
puts 'You decide to go back sleep. It is far too early.'
when 'get up'
Exposition.stretch
else
Exposition.getup_or_sleep?
end
end

Online Ruby editor outputs error “undefined method `chomp'” about gets.chomp

Usually when editing with Ruby I never would have to identify .chomp but now it needs me to define it and I don’t know how to define it properly to work the same way.
Code:
print "What's you're name?"
first_name= gets.chomp
print "What's you're last name?"
last_name= gets.chomp
print "What city are you from?"
city= gets.chomp
print "want to know you're name backwards?"
yes = true
no = false
if yes
puts #{first_name.reverse}
else
puts "Ok!"
print "you're first name is" #{first_name!}
print "you're last name is" #{last_name!}
print "you're city is" #{city!}
end
Editor:
https://www.jdoodle.com/execute-ruby-online/
I believe this may be an editor issue but please correct me if I’m wrong.
I was trying to make a questionnaire that takes the input then at the end spits it back out and asks if you would like to see your name backwards but instead I got an error I did not finish the other bit where it takes the information and spits it back out so ignore that. At first it just told me that chomp was not defined when using gets.chomp to take the input
but I never have to define .chomp before – this is a first. Please explain how to fix.
The error as seen in my code’s output:
What's you're name?
jdoodle.rb:2:in `<main>': undefined method `chomp' for nil:NilClass (NoMethodError)

Why is my Ruby code not executing as I expect it to?

I'm learning Ruby through the book Learn to Program by Chris Pine. In the book, there's an exercise which says:
Write a Deaf Grandma program. Whatever you say to grandma (whatever you type in), she should respond with HUH?! SPEAK UP, SONNY!, unless you shout it (type in all capitals). If you shout, she can hear you (or at least she thinks so) and yells back, NO, NOT SINCE 1938! To make your program really believable, have grandma shout a different year each time; maybe any year at random between 1930 and 1950. (This part is optional, and would be much easier if you read the section on Ruby's random number generator at the end of the methods chapter.) You can't stop talking to grandma until you shout BYE.
Hint: Don't forget about chomp! 'BYE'with an Enter is not the same as 'BYE' without one!
Hint 2: Try to think about what parts of your program should happen over and over again. All of those should be in your while loop.
I have written my code and it doesn't work as expected. Basically, when I input information, it follows the order in which the code was written. For example if I input "HELLO" it'll reply "HUH?! SPEAK UP, SONNY! but really it should be writing back "NO, NOT SINCE 1938!".
When I input 'BYE' nothing will come up unless I follow the order in which the code was written in (I hope that makes sense).
I have tried a lot of things, like not using the break (for the loop). I have tried to write it as one long piece of code without any ifs or else's.
Here is the code I have written:
puts 'Go speak to Grandma, she\'s in the kitchen!'
speaking = gets.chomp
if speaking == speaking.downcase
puts 'HUH?! SPEAK UP, SONNY!'
gets.chomp
while speaking == 'BYE'
puts 'BYE! COME AGAIN SOON!'
gets.chomp
break
end
else speaking == speaking.upcase
puts 'NO, NOT SINCE 1983!'
gets.chomp
end
I expect when I write HELLO to get the appropriate answer of 'NO, NOT SINCE 1983!'. Also, I expect the conversation to keep going because I have used gets.chomp on all pieces of the code. Sp why is the code stopping?
Problem in the code is that if ... else condition not wrapped within loop, so it would no be executed repeatedly.
Hint 2: Try to think about what parts of your program should happen
over and over again. All of those should be in your while loop
To make loop works you need wrap all repeatable lines within loop.
In your case loop should break only when input will be BYE
puts 'Go speak to Grandma, she\'s in the kitchen!'
speaking = gets.chomp
until speaking == 'BYE'
if speaking == speaking.upcase
puts 'NO, NOT SINCE 1983!'
else
puts 'HUH?! SPEAK UP, SONNY!'
end
# Get input before next loop
speaking = gets.chomp
end
puts 'BYE! COME AGAIN SOON!'
You don't need to check for downcase explicitly, only you care about is "does input contains only upper case characters"

When using rand() to generate numbers how can I verify that 'if' and 'else' statements guarantee me a correct answer?

I am attempting an exercise from a book that doesn't show any example code for a correct answer, so I'm not sure where I may have strayed. I've written what I felt was a good bit of code, but now I'm not sure if my code will return my statement for a correct guess.
The code:
prng = rand(10)
puts "What's your guess (1-9)?"
user_guess = gets.chomp
if user_guess == prng
puts "You guessed correctly!"
else
puts "Try again!"
end
I feel as though my if statement might be the issue here, because when I run the code it always returns my else statement. I've also tried narrowing the range of numbers so that my guess is more likely correct and I still didn't trigger the if statement's puts.
Any help is appreciated!
rand(10) returns an integer. gets returns a string. A string (in ruby) is never equal to an integer.
You need to either convert your input to an integer (gets.chomp.to_i) or your integer to a string: (rand(10).to_s) before you compare them.
Edit: If you need to debug further, you should check what the values actually are:
puts "The answer was #{prng.inspect} and you guessed #{user_guess.inspect}"

Ruby gets() not returning correct string [duplicate]

This question already has answers here:
Ruby: String Comparison Issues
(5 answers)
Closed 3 years ago.
I decided to give Ruby a go today after hearing all of the great things about it, but so far it has only been giving me a hard time. A long time ago I made a "search engine" while learning Python that just stores data in an array and checks if the search keyword is in it, and I've been trying to do the same thing in Ruby.
Although it wasn't as intuitive as it was in Python, I got the search functionality working. I'm having trouble working with user input, though. I want to check if the input equals insert, search, and quit, but it just doesn't work. I don't really know how to use gets, so I'm assuming the issue is gets-related.
while true
puts 'What do you want to do?'
choice = $stdin.gets
puts choice # => quit
if choice == 'quit'
break
end
end
The if statement doesn't work. What the heck am I doing wrong? This is trivial in C++ for God's sake!
I would really appreciate some help. Ruby is so foreign to me... thanks!
I think the gets includes the newline at the end of the input. try using gets.chomp instead
irb(main):001:0> input = $stdin.gets
hello
=> "hello\n"
irb(main):002:0> input = $stdin.gets.chomp
hello
=> "hello"
davidrac is correct, you need to chop off the \n
Quoting the answer from here
The problem is you are getting a newline character on your input from the user. while they are entering "y" you are actually getting "y\n". You need to chomp the newline off using the "chomp" method on string to get it to work as you intend

Resources