• 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.
• Extend your Deaf Grandma program: What if grandma doesn't want you
to leave? When you shout BYE, she could pretend not to hear you.
Change your previous program so that you have to shout BYE three times
in a row. Make sure to test your program: if you shout BYE three
times, but not in a row, you should still be talking to grandma.
Here is what I came up with:
#Grandma is deaf!
puts "Hey Sonny! It's your lovely Grandmother! How are yeah?"
response = "nope"
bye = 0
while bye < 3
response = gets.chomp
if response == (response.upcase and "BYE")
puts "Hmmm... I would prefer..."
bye = (bye+1)
end
if response != response.upcase
puts "Huh?! I CAN'T HEAR YOU!"
end
if (response == response.upcase and response != "BYE")
puts "NO! NOT SINCE " + (1930+rand(21)).to_s + "!"
end
end
puts "Hey Sonny! It's your lovely Grandmother! How are yeah?"
response = nil
bye = 0
while bye < 3
response = gets.chomp
if response == "BYE"
puts "Hmmm... I would prefer..."
bye = (bye+1)
elsif response == response.upcase
puts "NO! NOT SINCE " + (1930+rand(21)).to_s + "!"
else
puts "Huh?! I CAN'T HEAR YOU!"
end
end
Remember to set your bye counter to zero in every case except where
'BYE' is typed, to ensure three BYE's in a row are required. You can use
'next' to skip straight to the top of the next iteration, which means
you can put a single bye=0 at the end of the loop.
Also, I think there is some ambiguity in the original problem
description: what should happen if what you type contains neither upper
nor lower case letters? (e.g. empty text or only punctuation
characters?). In the code below I've let grandma have a snooze. I also
use the 'case' statement to match the response against a series of
values and regexp patterns.
puts "Hey Sonny, it's your Grandma! How are you?"
bye = 0
loop do
case gets.chomp
when "BYE"
bye += 1
break if bye >= 3
next
when /[a-z]/
puts "HUH?! SPEAK UP, SONNY!"
when /[A-Z]/
puts "NO, NOT SINCE #{rand(21)+1930}!"
else
puts "ZZZ"
end
bye = 0
end
But to be honest, I'd say that if...elsif...elsif...end is equally good.
I was doing stupid things with arrays and all sorts of dumb crap until I
came here and read this thread. Super good work. I wanted my Ruby script
to work with the three goodbyes extension exercise mentioned above.
Also—I like double quotes and #{} to get things done. In my neophyte
opinion, it's cleaner and less characters.
puts "TALK TO ME! SO LONELY!\n\n"
bye = 0
while bye < 3
response = gets.chomp
if response == "BYE"
puts "STAY AWHILE!?!"
bye = (bye+1)
elsif response == response.upcase
puts "NO! NOT SINCE #{1910+rand(41)}!"
bye = 0
else
puts "Huh?! I CAN'T HEAR YOU!"
bye = 0
end
end
If you make it a single string—it's 263 if you format it to one line and
strip my OCD new-line characters. It resets "bye" back down to zero if
it's not said three times straight.
For the full iteration of the problem (upcase, random years & triple BYE
in a row requests), I've got a slightly simpler structure, the code
makes sense to me structurally & intuitively:
puts 'Hello there, Sonny. It\'s your grandma!'
reply = gets.chomp
while reply != 'BYE'
if reply == reply.upcase
puts 'NO, NOT SINCE ' +(rand(21)+1930).to_s+ '!'
reply = gets.chomp
else
puts 'HUH?! SPEAK UP, SONNY!'
reply = gets.chomp
end
if reply == 'BYE'
puts 'CAN\'T HEAR YOU, DEAR!'
reply = gets.chomp
if reply == 'BYE'
puts 'STILL CAN\'T HEAR YOU, DEAR!'
reply = gets.chomp
if reply == 'BYE'
end
end
end
As a noob learning ruby, I am following the Chris Pine tutorial for
beginners.
However, the suggestions posted includes a lot of commands we have not
learned at this point of tutorial (Which really confuses me initially).
So here's my take:
puts 'Grandma: Hello, its\'s been while since you visit me. Come here
and talk to Grandma.'
index = 0
while index != 3
respond = gets.chomp
if respond == 'BYE'
index = index + 1
else
index = 0
if respond == respond.upcase
puts 'NO, NOT SINCE '+(rand(20)+1930).to_s+' !'
else
puts 'HUH?! SPEAK UP, SONNY!'
end
end
end
puts 'Hi! My name Deaf Grandma'
check = 0
while check <3
if (input = gets.chomp) == input.upcase
puts "NO! NOT SINCE " + (1930+rand(21)).to_s + "!"
if input == 'BYE'
check = check + 1
else
check = 0
end
else
puts 'HUH?! SPEAK UP, SONNY!'
end
end
puts 'Goodbye! See you later!'
I like this one, but you forgot to reset this check to zero, otherwise
it will end the program if the user inputs 'BYE' 3x non-sequentially
(i.e 'BYE', 'bye', 'BYE, 'BYE')
else
puts 'HUH?! SPEAK UP, SONNY!'
check = 0 #need this extra reset to zero
Still LOTS of repetition here. DRY: Don't Repeat Yourself, not only
saves typing, and time, but might also lead to better understanding of
algorithms. See if you can write it with only one gets per loop.
···
On Fri, Feb 8, 2013 at 12:25 PM, Anna Fedorova <lists@ruby-forum.com> wrote:
For the full iteration of the problem (upcase, random years & triple BYE
in a row requests), I've got a slightly simpler structure, the code
makes sense to me structurally & intuitively:
puts 'Hello there, Sonny. It\'s your grandma!'
reply = gets.chomp
while reply != 'BYE'
if reply == reply.upcase
puts 'NO, NOT SINCE ' +(rand(21)+1930).to_s+ '!'
reply = gets.chomp
else
puts 'HUH?! SPEAK UP, SONNY!'
reply = gets.chomp
end
if reply == 'BYE'
puts 'CAN\'T HEAR YOU, DEAR!'
reply = gets.chomp
if reply == 'BYE'
puts 'STILL CAN\'T HEAR YOU, DEAR!'
reply = gets.chomp
if reply == 'BYE'
end
end
end
My solution was very similar. Any advice from the peanut gallery on
making this code cleaner? (Pardon all the comments, it helps me figure
things out.)
#Deaf Grandma w/ extension
#Set initial counter
count=0
#Create Loop Conditions
while count<3
response=gets.chomp
if response==("bye").upcase
# Grandma ignores but the count increases by 1
count+=1
# (puts count
# this was an internal test)
elsif response==response.upcase
# Grandma respond with random year
puts ("No, not since ").upcase+(rand(21)+1930).to_s
count=0
else
# Grandma can't hear
puts ("Huh?! Speak up sonny!").upcase
count=0
end
# Grandma says bye after 3 count
if count==3
puts "OK. Fine. Just leave then."
end
puts 'Grandma: Hello, its\'s been while since you visit me. Come here
and talk to Grandma.'
If you use double-quotes around the string, you won\'t, er, I mean,
won't, need to escape the apostrophe. Some folks say that using
double-quotes ALL the time is less confusing, saving enough
programmer-time to be worth the extra execution-time from Ruby
checking for any string interpolation it needs to do. (See below.)
puts 'NO, NOT SINCE '+(rand(20)+1930).to_s+' !'
Has the book gotten to string interpolation yet? Long story short,
that's embedding a variable within a string. You might have seen it
in Perl or shell scripts as something like "Hello, $NAME!". In Ruby
it's done with #{}, putting the Ruby expression inside the {}.
However, it requires use of *double* quotes instead of single. (This
is true in most languages that support string interpolation.) So for
instance, the above would be, in more idiomatic Ruby:
puts "NO, NOT SINCE #{(rand(20)+1930)}!"
-Dave
···
On Sun, Sep 8, 2013 at 4:41 AM, ChangSeng S. <lists@ruby-forum.com> wrote:
--
Dave Aronson, the T. Rex of Codosaurus LLC,
secret-cleared freelance software developer
taking contracts in or near NoVa or remote.
See information at http://www.Codosaur.us/\.
On Sep 8, 2013 10:27 AM, "Dave Aronson" <rubytalk2dave@davearonson.com> wrote:
On Sun, Sep 8, 2013 at 4:41 AM, ChangSeng S. <lists@ruby-forum.com> wrote:
> puts 'Grandma: Hello, its\'s been while since you visit me. Come here
> and talk to Grandma.'
If you use double-quotes around the string, you won\'t, er, I mean,
won't, need to escape the apostrophe. Some folks say that using
double-quotes ALL the time is less confusing, saving enough
programmer-time to be worth the extra execution-time from Ruby
checking for any string interpolation it needs to do. (See below.)
> puts 'NO, NOT SINCE '+(rand(20)+1930).to_s+' !'
Has the book gotten to string interpolation yet? Long story short,
that's embedding a variable within a string. You might have seen it
in Perl or shell scripts as something like "Hello, $NAME!". In Ruby
it's done with #{}, putting the Ruby expression inside the {}.
However, it requires use of *double* quotes instead of single. (This
is true in most languages that support string interpolation.) So for
instance, the above would be, in more idiomatic Ruby:
puts "NO, NOT SINCE #{(rand(20)+1930)}!"
-Dave
--
Dave Aronson, the T. Rex of Codosaurus LLC,
secret-cleared freelance software developer
taking contracts in or near NoVa or remote.
See information at http://www.Codosaur.us/\.
puts "Hey Sonny! It's your lovely Grandmother! How are you?"
response = gets.chomp
bye = 0
while bye < 1
if response != response.upcase
puts "Huh?! I CAN'T HEAR YOU!"
end
if (response == response.upcase and response != "BYE")
puts "NO! NOT SINCE " + (1930+rand(21)).to_s + "!"
end
if response == "BYE"
puts "GOOD BYE, SONNY!"
bye = (bye+1)
end
response = gets.chomp
end
I'm a noob, but this seems cleaner to me. I know there is a way to write
it with out repeating the "if" statements three times but at least it
works:) The only other thing that bothers me is you have to press enter
at the end to return to the command prompt. If anyone has an example on
how to fix it that would be sweet.