Tutorial challenge program help

Hello all im really new to ruby as in a few days and getting into it. i
was following a tutorial found on
http://pine.fm/LearnToProgram/?Chapter=00 in later chapters it made a
challenge to write a program involving a looping a deaf grandma i
started it and have it for the most part working buts its doing a few
things that i dont fully understand im guessing these are bugs O.o?

  reply = ' '
  replytt = ' '
puts 'Ahh theres my grandson'
  while replytt != 'BYE'
  while reply != 'BYE'
    reply = gets.chomp
  if reply == reply.upcase
    puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
reply = gets.chomp
  else
    puts 'WHAT\'S THAT SONNY SPEAK UP!'
    reply = gets.chomp
end
end
  if reply == 'BYE'
    puts 'Do you really have to go?'
    replyt = gets.chomp
    reply = replyt
  if replyt == 'BYE'
    puts 'Don\'t you wanna hear about the time I met your granda?'
    replytt = gets.chomp
    replyt = replytt
    reply = replyt
  else
    puts 'WHAT\'S THAT SONNY SPEAK UP!'
    replyt = replytt
    reply = replyt
    reply = gets.chomp
end
end
end
puts 'Come back and visit your old granny again soon.'
puts 'Ill tell you the time I...'
puts 'zzzz...'

a few things first off since i cannot seem to find it on google i dont
know how to make rand pop out anything thats not 0- a number for
instance i wanted it to be like the tutorial said and make it 1930- 1950
for the year the second is during if reply == reply.upcase it gives me a
blank line i have to hit enter again before it gives the No not since
[year] also during the second BYE if replyt == 'BYE' even if i put an
answer that isnt in caps lock it gives it me a respons as if it was.
thats all i can remeber right now also any tips on just making the whole
thing smoother would be appreciated. I'm quite proud of this as its my
first real project i did.

···

--
Posted via http://www.ruby-forum.com/.

Chris Logan wrote:

Hello all im really new to ruby as in a few days and getting into it. i
was following a tutorial found on
http://pine.fm/LearnToProgram/?Chapter=00 in later chapters it made a
challenge to write a program involving a looping a deaf grandma i
started it and have it for the most part working buts its doing a few
things that i dont fully understand im guessing these are bugs O.o?

  reply = ' '
  replytt = ' '
puts 'Ahh theres my grandson'
  while replytt != 'BYE'
  while reply != 'BYE'
    reply = gets.chomp
  if reply == reply.upcase
    puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
reply = gets.chomp
  else
    puts 'WHAT\'S THAT SONNY SPEAK UP!'
    reply = gets.chomp
end
end
  if reply == 'BYE'
    puts 'Do you really have to go?'
    replyt = gets.chomp
    reply = replyt
  if replyt == 'BYE'
    puts 'Don\'t you wanna hear about the time I met your granda?'
    replytt = gets.chomp
    replyt = replytt
    reply = replyt
  else
    puts 'WHAT\'S THAT SONNY SPEAK UP!'
    replyt = replytt
    reply = replyt
    reply = gets.chomp
end
end
end
puts 'Come back and visit your old granny again soon.'
puts 'Ill tell you the time I...'
puts 'zzzz...'

a few things first off since i cannot seem to find it on google i dont
know how to make rand pop out anything thats not 0

What output do you get for this:

puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'

and what about this:

puts rand(5)
puts rand(10)

for
instance i wanted it to be like the tutorial said and make it 1930- 1950
for the year

For the 30-50 part, how about getting a random number that is greater
than or equal to 0 and less than 20 and then adding 30 to it?

the second is during if reply == reply.upcase it gives me a
blank line i have to hit enter again before it gives the No not since
[year]

In your opinion, what does the last line here do:

  reply = gets.chomp
  if reply == reply.upcase
    puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
    reply = gets.chomp

also during the second BYE if replyt == 'BYE' even if i put an
answer that isnt in caps lock it gives it me a respons as if it was.

Your code is a mess. You need to choose an indenting format. Here is
what I recommend:

x = 1

while x != 10
  if x == 1
    puts "hello"
  end

  break
end

Note:

1) The first "end" is indented the same amount as 'if', and denotes the
end of the if statement.
2) Everything inside the while statement is indented more than 'while'
3) The last 'end' matches the indenting of 'while', and denotes the end
of the while loop.

Without proper indenting, you will never be able to follow the logic of
your code.

···

--
Posted via http://www.ruby-forum.com/\.

Hi, Chris, I think that extracting pieces of functionality out into methods
would make your program a lot simpler. I know it can be frustrating to work
for 6 hours on a project like this, so let me show you how I would approach
the problem. I put a lot of comments in, because I don't know how much you
understand, forgive me if I stress things you are already well aware of.

# this method gets the input from the user
# it sets it into the instance variable @input
# we use an instance variable because it will continue
# to exist outside the method. You know it is an instance
# variable because it begins with an @ symbol. If it did not, it
# would be a local variable, and "die" after the method returned.

···

On Tue, Sep 8, 2009 at 8:13 PM, Chris Logan <t-logan3@hotmail.com> wrote:

Hello all im really new to ruby as in a few days and getting into it. i
was following a tutorial found on
http://pine.fm/LearnToProgram/?Chapter=00 in later chapters it made a
challenge to write a program involving a looping a deaf grandma i
started it and have it for the most part working buts its doing a few
things that i dont fully understand im guessing these are bugs O.o?

reply = ' '
replytt = ' '
puts 'Ahh theres my grandson'
while replytt != 'BYE'
while reply != 'BYE'
   reply = gets.chomp
if reply == reply.upcase
   puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
reply = gets.chomp
else
   puts 'WHAT\'S THAT SONNY SPEAK UP!'
   reply = gets.chomp
end
end
if reply == 'BYE'
   puts 'Do you really have to go?'
   replyt = gets.chomp
   reply = replyt
if replyt == 'BYE'
   puts 'Don\'t you wanna hear about the time I met your granda?'
   replytt = gets.chomp
   replyt = replytt
   reply = replyt
else
   puts 'WHAT\'S THAT SONNY SPEAK UP!'
   replyt = replytt
   reply = replyt
   reply = gets.chomp
end
end
end
puts 'Come back and visit your old granny again soon.'
puts 'Ill tell you the time I...'
puts 'zzzz...'

a few things first off since i cannot seem to find it on google i dont
know how to make rand pop out anything thats not 0- a number for
instance i wanted it to be like the tutorial said and make it 1930- 1950
for the year the second is during if reply == reply.upcase it gives me a
blank line i have to hit enter again before it gives the No not since
[year] also during the second BYE if replyt == 'BYE' even if i put an
answer that isnt in caps lock it gives it me a respons as if it was.
thats all i can remeber right now also any tips on just making the whole
thing smoother would be appreciated. I'm quite proud of this as its my
first real project i did.
--
Posted via http://www.ruby-forum.com/\.

#
# the last line of a method is always returned, so in this case,
# we set the variable @input, and return it's value
# this is because the assignment operator, =, is itself a method
# which returns the value that was assigned.
def get_input
  print "Say to deaf grandma: " #prompts the user for information
  @input = gets.chomp #set @input, return it's value
end

# this function returns a year from 1930 - 1950
def get_year
  # we use double quotes, then embed the values we want within them
  # when we do it this way, the .to_s method is automatically called
  # on whatever the value happens to be.
  # so this is the same as "19" + (rand(21)+30).to_s
  "19#{rand(21)+30}" #variability of 21 years, offset by 30 years
end

# this is a little trickier, here we open up the String class
# and we add the method to it called shouted? This will then be
# available to any given string.
# We can access that string with the self variable
#
# So if the string is equal to itself in upcase, then it has been
# shouted, this value will be returned
# try it out with something like
# p "did not shout".shouted?
# p "DID SHOUT".shouted?
# when we put a question mark on the end of a function or method,
# it indicates that a boolean value will be returned. A boolean
# value is just true or false.
class String
  def shouted?
    self == self.upcase #returns true if the string is uppercase
  end
end

# now that we have made our functions and methods to help us, our
# program logic becomes much simpler, the entire program can be
# written like this
while get_input != "BYE"
  # remember, our instance variable @input
  # was set by the get_input method, it is the String that the user
  # submitted. Since it is a String, and we added the .shouted?
  # method to the String class, we can call that method on it
  if @input.shouted?
    puts "NO, NOT SINCE #{get_year}!" #embed the year in the string
  else
    puts "HUH?! SPEAK UP, SONNY!"
  end
  puts #a blank line to make it more legible
end

puts "BYE, SONNY!" #grandma's last response

7stud -- wrote:

What output do you get for this:
puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'

i get "No not since [1900-1949] intergers only

and what about this:

puts rand(5) 0-4 intergers only
puts rand(10) 0-9 intergers only

for
instance i wanted it to be like the tutorial said and make it 1930- 1950
for the year

For the 30-50 part, how about getting a random number that is greater
than or equal to 0 and less than 20 and then adding 30 to it?
hmmmm i think i tried something like that and got the cannot convert fixnum into string error many times or something it seems ill have to play with the rand method more ahhh i remember i had a problem figuring out how to add intergers and then convert the sum into a string

the second is during if reply == reply.upcase it gives me a
blank line i have to hit enter again before it gives the No not since
[year]

In your opinion, what does the last line here do:

  reply = gets.chomp
  if reply == reply.upcase
    puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
    reply = gets.chomp

reply = gets.chomp? that means im resetting the variable named reply to equal the method get string so that it will be whatever i manually enter with the chomp method so that it ignores my enter keystroke in a broader sense it keeps me in the loop section of the program while providing a way out. im sorry i know im a naturally dense person and i do not get where your going with that one

also during the second BYE if replyt == 'BYE' even if i put an
answer that isnt in caps lock it gives it me a respons as if it was.

Your code is a mess. You need to choose an indenting format. Here is
what I recommend:

x = 1

while x != 10
  if x == 1
    puts "hello"
  end

  break #im sorry is this a command or just showing you put a line between

           #them?

end

Note:

1) The first "end" is indented the same amount as 'if', and denotes the
end of the if statement.
2) Everything inside the while statement is indented more than 'while'
3) The last 'end' matches the indenting of 'while', and denotes the end
of the while loop.

Without proper indenting, you will never be able to follow the logic of
your code.

Wow i guess i was right not to post what i first had as this is the
cleaned up version <.< as i said im very new to this and im sorry
perhaps ill get more ocd at it with time here lemme try to fix it lol

reply = ' '
replytt = ' '

puts 'Ahh theres my grandson'

while replytt != 'BYE'
while reply != 'BYE'

  reply = gets.chomp

                if reply == reply.upcase
      puts 'No not since 19' + (rand(5)).to_s + (rand(10)).to_s + '!'
#Sorry
      reply = gets.chomp
    else
      puts 'WHAT\'S THAT SONNY SPEAK UP!'
      reply = gets.chomp
    end

end #ahh i see what you mean i have no idea what this belongs too x.x
#im guessing one of the whiles this being all the way up here while the
other
#is at the bottom makes me think that possibly it is one of the problems
#bah i tried it it isnt still one step forward for understanding.

                if reply == 'BYE'
      puts 'Do you really have to go?'
      replyt = gets.chomp
      reply = replyt

                if replyt == 'BYE'
      puts 'Don\'t you wanna hear about the time I met your granda?' #
sorry forum post wont let me line this up right
      replytt = gets.chomp
      replyt = replytt
      reply = replyt

                else
      puts 'WHAT\'S THAT SONNY SPEAK UP!'
      replyt = replytt
      reply = replyt
      reply = gets.chomp

                end
    end

end

puts 'Come back and visit your old granny again soon.'
puts 'Ill tell you the time I...'
puts 'zzzz...'

i had a little problem keeping up with the ends and how many i needed i
expected the 'orderedness' to come with practice

Once again im sorry i realise this is a newb question for a newb program
and i remeber how i hated frivolous newb WoW questions. But he who asks
a question is a fool for five minutes. he who doesnt is a fool forever.
but i dont even know what to type in the google bar for this and after i
spent 6 hours not going anywhere with it i decided to find people to
help and this looked like the best site i found so far i think i was
right as my brother told me this program would get laughed at as i said
im proud of it its my first one i did the hello world and a program that
got your name and added all the chars together but those just did not
impress me like this one did. =)

hmm i think that wraps up this post i look foward to your next reply =)

···

--
Posted via http://www.ruby-forum.com/\.

Josh Cheek wrote:

# it sets it into the instance variable @input
# we use an instance variable because it will continue
# to exist outside the method. You know it is an instance
# variable because it begins with an @ symbol. If it did not, it
# would be a local variable, and "die" after the method returned.

I do not fully understand this.

# the last line of a method is always returned, so in this case,
# we set the variable @input, and return it's value
# this is because the assignment operator, =, is itself a method
# which returns the value that was assigned.
def get_input
  print "Say to deaf grandma: " #prompts the user for information
  @input = gets.chomp #set @input, return it's value
>
# p "did not shout".shouted?
# p "DID SHOUT".shouted?
# when we put a question mark on the end of a function or method,
# it indicates that a boolean value will be returned. A boolean
# value is just true or false.
class String
  def shouted?
    self == self.upcase #returns true if the string is uppercase
  end
end

Oh wow, I understood this that is really cool.

puts "NO, NOT SINCE #{get_year}!" #embed the year in the string

  else
Do I use the # symbol? I read that that denotes a comment and anything
after it would be ignored by Ruby.

Hmm, I'll mull this over. This is really great information my next
project should go MUCH easier, but I still don't understand why during
reply == reply.upcase it was giving that blank line. I've reread the
code a lot and I have no clue what would cause that. Thanks a bunch!

···

On Tue, Sep 8, 2009 at 8:13 PM, Chris Logan <t-logan3@hotmail.com> > wrote:

--
Posted via http://www.ruby-forum.com/\.

bah i spent forever trying to make that nice and neat and then when it
posted it all changed T_T im gonna go cry in a corner now

···

--
Posted via http://www.ruby-forum.com/.

Josh Cheek wrote:
> # it sets it into the instance variable @input
> # we use an instance variable because it will continue
> # to exist outside the method. You know it is an instance
> # variable because it begins with an @ symbol. If it did not, it
> # would be a local variable, and "die" after the method returned.
I do not fully understand this.

Hi, Chris, for right now, I think it is probably best to just accept that
you don't understand it, and just treat it like a variable that you have
access to inside and outside of functions. When you get to the OOP (Object
Oriented Programming) portions of your learning, it will become clear, I
think. But for me to explain it would require some OOP theory.

But when you get there, you will learn about scope, different types of
variables, the differences between functions and methods (granted that I
usually just call everything a method), and so on. It should then be clear
to you why a variable called @something works differently than a variable
called something. You'll also learn why you can call "my string".shouted?
rather than doing something like shouted?( "my_string" )

Until then, you learn about instance variables and OOP, it would probably be
best to just chant the Apple mantra of "it just works".

An alternative way to do this would be like this:

def get_input
  print "Say to deaf grandma: " #prompts the user for information
  gets.chomp #return the input
end

Then down where we use it, instead of saying

while get_input != "BYE"
  if @input.shouted?
    puts "NO, NOT SINCE #{get_year}!"
  else
    puts "HUH?! SPEAK UP, SONNY!"
  end
  puts
end

we could say:

while (input = get_input) != "BYE"
  if input.shouted?
    puts "NO, NOT SINCE #{get_year}!"
  else
    puts "HUH?! SPEAK UP, SONNY!"
  end
  puts
end

The difference here is that it returns the input, then we assign it to a
local variable with the (input = get_input) and then compare that input to
the string "BYE" This is what I would probably do in reality, but I thought
the (input = get_input) != "BYE" would be more confusing.

The reason I do it that way is so that the input is set where it is
compared, that saves me from a lot of edge cases like the first time through
the loop not having the value of input be initialized, or other esoteric
ordering of when to get input verses when to respond to it. You'll notice it
was in trying to handle this logic that you ended up prompting two times,
causing the bug you noted. So that is why I wanted the assignment to take
place right where the comparison is made.

puts "NO, NOT SINCE #{get_year}!" #embed the year in the string else

Do I use the # symbol? I read that that denotes a comment and anything
after it would be ignored by Ruby.

To embed something in a string, you have the opening and closing " symbols,
and inside them you then put #{ ... } where whatever is in there gets
interpreted and placed into the string. The # symbol does indicate a
comment, but not when it is inside of a string. Note that you need to use
double quotation " to do this, single quotation ' will not embed strings.

* Except for very small snippets, code should probably not go in the post.
There are sites (such as pastie.org) which are perfect for this purpose
and will even syntax highlight your code.

I've had people here tell me not to use external sites (I posted some of my
code on pastie) as it does not preserve the code if the site goes down.

···

On Wed, Sep 9, 2009 at 2:44 PM, Chris Logan <t-logan3@hotmail.com> wrote:

> On Tue, Sep 8, 2009 at 8:13 PM, Chris Logan <t-logan3@hotmail.com> > > wrote:

Chris Logan wrote:

Josh Cheek wrote:

# it sets it into the instance variable @input
# we use an instance variable because it will continue
# to exist outside the method. You know it is an instance
# variable because it begins with an @ symbol. If it did not, it
# would be a local variable, and "die" after the method returned.

I do not fully understand this.

I suggest you not try to understand. I would never write code like
that, and I suggest you never write code like that either.

# the last line of a method is always returned, so in this case,
# we set the variable @input, and return it's value
# this is because the assignment operator, =, is itself a method
# which returns the value that was assigned.
def get_input
  print "Say to deaf grandma: " #prompts the user for information
  @input = gets.chomp #set @input, return it's value
>
# p "did not shout".shouted?
# p "DID SHOUT".shouted?
# when we put a question mark on the end of a function or method,
# it indicates that a boolean value will be returned. A boolean
# value is just true or false.
class String
  def shouted?
    self == self.upcase #returns true if the string is uppercase
  end
end

Oh wow, I understood this that is really cool.

Don't get too enamored of that either. That's derisively called "monkey
patching", and monkey patching is another bad habit that will make your
code hard to read and understand.

puts "NO, NOT SINCE #{get_year}!" #embed the year in the string

  else
Do I use the # symbol? I read that that denotes a comment and anything
after it would be ignored by Ruby.

Yes and no. In this case, no. The # symbol in that line of code is part
of the syntax for what's called "string interpolation". Here is a
simple example:

x = 2

puts "The variable x is equal to #{x}."

--output:--
The variable x is equal to 2.

Inside a string you can use the syntax:

#{some_var_name}

to cause the variable's value to be inserted into the string.

Hmm, I'll mull this over. This is really great information my next
project should go MUCH easier

Advice is freely given on the internet. Some of it is bad advice.

···

On Tue, Sep 8, 2009 at 8:13 PM, Chris Logan <t-logan3@hotmail.com> >> wrote:

--
Posted via http://www.ruby-forum.com/\.

Chris Logan wrote:

bah i spent forever trying to make that nice and neat and then when it
posted it all changed T_T im gonna go cry in a corner now

What are you using for a text editor? You should use a text editor that
converts tabs to spaces. Also, remember that ruby indenting is 2
spaces. Then you can just copy and paste your code into the editor
window when you post code.

···

--
Posted via http://www.ruby-forum.com/\.

7stud -- wrote:

Chris Logan wrote:

bah i spent forever trying to make that nice and neat and then when it
posted it all changed T_T im gonna go cry in a corner now

Also, I should mention: your posts are totally unacceptable. Before
learning to program, you need to learn something much more important:
how to write. The people who post here and answer questions are not
illiterate high school dropouts. Your sentences need to start with
capital letters and end with some form of punctuation, e.g. a period.
Writing a whole paragraph with no punctuation my be fine for
communicating with your MySpace friends, but it is not acceptable in an
academic environment.

You've also somehow managed to post text with no newlines, which means
your text is all on one line. That makes your text more than one screen
wide, which makes your post very irritating to try to read.

···

--
Posted via http://www.ruby-forum.com/\.

Chris Logan wrote:

bah i spent forever trying to make that nice and neat and then when it posted it all changed T_T im gonna go cry in a corner now

Also, I should mention: your posts are totally unacceptable. Before learning to program, you need to learn something much more important: how to write. The people who post here and answer questions are not illiterate high school dropouts. Your sentences need to start with capital letters and end with some form of punctuation, e.g. a period. Writing a whole paragraph with no punctuation my be fine for communicating with your MySpace friends, but it is not acceptable in an academic environment.

7stud, please remember the mantra of this mailing list: MINASWAN.

Matz is nice and so we are nice.

I'm quite proud of this as its my first real project i did.

Congratulations - it's a nice first effort.

About the formatting - sometimes 'tab' characters get eaten on
mailing lists and forums. As a previous post mentioned, your editor should be able to be set so that it indents with spaces instead of tabs. Or, alternately, your editor should be able to
convert tabs to spaces for you on the text before you paste it
into a post.

Regarding your question about random numbers, here's a
hint:

  puts "A number between 1000 and 1049 is: #{1000 + rand(50)}"

Regards,

Bill

···

"7stud --" <bbxx789_05ss@yahoo.com> wrote:
"Chris Logan" <t-logan3@hotmail.com> wrote:

7stud -- wrote:

Also, I should mention: your posts are totally unacceptable. Before
learning to program, you need to learn something much more important:
how to write. The people who post here and answer questions are not
illiterate high school dropouts. Your sentences need to start with
capital letters and end with some form of punctuation, e.g. a period.
Writing a whole paragraph with no punctuation my be fine for
communicating with your MySpace friends, but it is not acceptable in an
academic environment.

You've also somehow managed to post text with no newlines, which means
your text is all on one line. That makes your text more than one screen
wide, which makes your post very irritating to try to read.

     My apologies. I rarely do so on the internet till it has just
become a
habit. I did not think it would bother anyone as it does not bother
others
I interact with on the internet. As for the new line error, once again
my apologies, I have never used a forum like this before and I did not
realise it would post like that.

···

--
Posted via http://www.ruby-forum.com/\.

7stud -- wrote:
> Also, I should mention: your posts are totally unacceptable. Before
> learning to program, you need to learn something much more important:
> how to write. The people who post here and answer questions are not
> illiterate high school dropouts. Your sentences need to start with
> capital letters and end with some form of punctuation, e.g. a period.
> Writing a whole paragraph with no punctuation my be fine for
> communicating with your MySpace friends, but it is not acceptable in
an
> academic environment.
>
> You've also somehow managed to post text with no newlines, which
means
> your text is all on one line. That makes your text more than one
screen
> wide, which makes your post very irritating to try to read.

Chris wrote:

     My apologies. I rarely do so on the internet till it has just
become a
habit. I did not think it would bother anyone as it does not bother
others
I interact with on the internet. As for the new line error, once again
my apologies, I have never used a forum like this before and I did not
realise it would post like that.

Don't feel too bad, I think 7stud is getting a bit over excited here
(though his points are quite valid). As you are new to this kind of a
list, a few pointers:

* Spelling and grammar is important here. You are dealing with a large
number of academics, and they notice and care about these things. You
will likely find you are not taken seriously if your grammar is lacking.

* There are many here who use command line mail clients which don't
word wrap automatically, thus it's helpful to monitor your own
column length. As I use Outlook I wind up doing this by hand (great fun).
A good rule of thumb is a column length of no more than 80 characters.

* Except for very small snippets, code should probably not go in the post.
There are sites (such as pastie.org) which are perfect for this purpose
and will even syntax highlight your code.

* Replacing tabs with spaces was mentioned earlier. This has long been
a holy war, which no doubt shall continue for years to come. Go with
whichever you prefer. It is worth noting that the ruby community seems
to predominantly prefer spaces with 2 spaces per tab.

I think most of your issues with your original program have been addressed.
Is there anything you are still lost on?

Walton

Is there anything you are still lost on?

I still do not know what gave that blank line as i said before. I was
hoping
to understand what caused that so i can avoid it in the future. Thank
you for all the tips.

···

--
Posted via http://www.ruby-forum.com/\.

Chris:

I still do not know what gave that blank line as i said before. I was
hoping
to understand what caused that so i can avoid it in the future. Thank
you for all the tips.

I've cleaned up your code and placed it on pastie:
http://pastie.org/611591

Notice line's 9 and 12 (the if and else) you do:
reply = gets.chomp

You also however do so at the beginning of your while loop (line 6)
so, your code at line 9 sets reply to the user input, then jumps back
to the start of your loop and proceeds to do it again. Thus requiring
2 sets of input.

Does that make sense?

Notice line's 9 and 12 (the if and else) you do:
reply = gets.chomp

You also however do so at the beginning of your while loop (line 6)
so, your code at line 9 sets reply to the user input, then jumps back
to the start of your loop and proceeds to do it again. Thus requiring
2 sets of input.

Does that make sense?

Yes, actually yes it does. I get it now. Thanks a bunch for this.

Hi, Chris, for right now, I think it is probably best to just

accept that you don't understand it.

Have to agree with this it feels like I'm missing step two of three.

Advice is freely given on the internet. Some of it is bad advice.

Aye but in the words of Fred Brooks
Good judgement comes from experience. Experience comes from bad
judgement.

I do not know if these are good ideas or bad ideas, all I do know is the
more I learn the more I'm utterly fascinated by it. It seems I have a
lot more to learn. Thank you everyone for your tips.

···

--
Posted via http://www.ruby-forum.com/\.

Well, after hearing all of your guy's advice, I thought it over and
finally came up with the answers. Its monkey patched (those words make
me laugh) but it works bug free and you have no idea how elated I am at
that (well maybe you do). Monkey patching may be bad but it got my job
done. Maybe after I get a lot more experience I will find out how to do
this without it but for now I'm satisfied and moving on in the tutorial.
I was going to post it but I remebered what one of the earlier posts
said so I did this.

http://pastie.org/612032

I was hoping for a couple honest opionions.
Any comments or any more tips are greatly appreciated.
You have all been a huge help. Thank you all.

Chris

···

--
Posted via http://www.ruby-forum.com/.

you should come back to it and evaluate your progress, maybe try to refactor
the code to incorporate the experience you have gained.

There are a few things, notice the syntax highlighting on line 46, you need
to either escape that apostrophe, or else wrap your string in double quotes.

You have

class String
  def monkey?
    self != (Math::PI) and self != 'BYE'
  end
end

But this is a little tricky. Your variable was initially a String, but when
you assigned it the value of Math::PI, it became a Float. So that method
monkey? does not exist on for Floats. Since it is defined in the String
class, self will always be a string, so it can never be equal to Math::PI

Monkey patching just means that you are adding functionality to the class in
some unofficial way, changing it (usually at run-time) with your own code.
It can cause issues, and be unintuitive, so it is sometimes looked down on,
but that doesn't mean it should always be avoided. In fact, I'd argue that
in a small program like this, which is built around the state of the string
being shouted or not (it is the deaf grandma problem, after all), that it
should be very intuitive what that method does, it is simple and
straightforward, and is a cleaner solution, both in terms of OO, and in
terms of the nature of the problem, than defining a function to receive this
as a parameter.

However, your monkey method would be much better served as a function that
receives a value, because then it can receive any value at all (where
shouted? indicates the state of the string, monkey? does not, because a
Float is not a string).

So you could do something like this

def monkey?( var )
  var != Math::PI && var != "BYE"
end

Then instead of saying something like

elsif reply.monkey?

you would say

elsif monkey?(reply)

Passing the reply to the monkey?() function instead of calling the .monkey?
method on it.

Now, that said, if you follow your program logic, you have

if reply == (Math::PI)
  puts 'Do you know when I was your age I was a model?'
  reply = gets.chomp
end

which gets executed first, so really, reply will never be Math::PI when it
gets to the reply.mokey? call, because this code will ensure that it becomes
the input.

Also, as far as using constants goes, Math::PI doesn't make a lot of sense.
I understand thats the point of it :wink: but I think a better choice would be
to use a symbol. You can think of a symbol as a string with the properties
of a numeric constant (granted there is more to it than that). Strings are
defined like this "string" and symbols are defined like this :symbol So I
would suggest that instead of using Math::PI, you use a symbol that makes
sense for you, something like :uninitialized Then when you look at your code
later, seeing :uninitialized in all places where you currently have Math::PI
will make a lot more sense.

Also, an uninitialized variable is nil by default, you should probably try
to get comfortable with this, because that will be the case for almost
everything in Ruby. So with that understanding, you could bypass the need
for a constant altogether.

Hope that helps, glad you're making progress, and keep at it :slight_smile:

···

On Thu, Sep 10, 2009 at 2:54 AM, Chris Logan <t-logan3@hotmail.com> wrote:

Well, after hearing all of your guy's advice, I thought it over and
finally came up with the answers. Its monkey patched (those words make
me laugh) but it works bug free and you have no idea how elated I am at
that (well maybe you do). Monkey patching may be bad but it got my job
done. Maybe after I get a lot more experience I will find out how to do
this without it but for now I'm satisfied and moving on in the tutorial.
I was going to post it but I remebered what one of the earlier posts
said so I did this.

http://pastie.org/612032

I was hoping for a couple honest opionions.
Any comments or any more tips are greatly appreciated.
You have all been a huge help. Thank you all.

Chris
--
Posted via http://www.ruby-forum.com/\.

Hi, Chris, I'm glad you got it working. After you code a little bit longer,

Josh Cheek wrote:

There are a few things, notice the syntax highlighting on line 46, you
need
to either escape that apostrophe, or else wrap your string in double
quotes.

O jeez, I did not even notice that I just changed it because I noticed I
forgot the apostrophe.

But this is a little tricky. Your variable was initially a String, but
when
you assigned it the value of Math::PI, it became a Float. So that method
monkey? does not exist on for Floats. Since it is defined in the String
class, self will always be a string, so it can never be equal to
Math::PI

I think I grasped that

terms of OO

I'm sorry, in terms of what?

However, your monkey method would be much better served as a function
that
receives a value, because then it can receive any value at all (where
shouted? indicates the state of the string, monkey? does not, because a
Float is not a string).

No I'm sorry I got lost there I am not entirely sure what the problem
is. I expect it is my lack of knowledge and experience.

def monkey?( var )
  var != Math::PI && var != "BYE"
end

So let me get this one straight. Doing it like this would mean that
instead of calling monkey? on the variable i would call the variable on
the monkey? method.? I'm sorry, I did not truly understand the
difference in there would it not be the exact same thing?

if reply == (Math::PI)
  puts 'Do you know when I was your age I was a model?'
  reply = gets.chomp
end

which gets executed first, so really, reply will never be Math::PI when
it
gets to the reply.mokey? call, because this code will ensure that it
becomes
the input.

Sorry it was giving me a problem where it met two conditions at once and
I'm not sure anymore of the exact problem but in the end I needed reply
to originally be out of the loop but still give me a one time input in
the loop. I also did not want the one time input to accidently be
entered so I just thought what is something no one will ever type in and
Pi being a never ending number seemed like a really good idea.

Also, as far as using constants goes, Math::PI doesn't make a lot of
sense.
I understand thats the point of it :wink: but I think a better choice would
be
to use a symbol. You can think of a symbol as a string with the

As I said I did not want it to be accidently entered and being a gamer I
know the lengths some people will go to to break the game.

later, seeing :uninitialized in all places where you currently have
Math::PI
will make a lot more sense.

Hmm. So if i use :uninitialised then it doesnt really mean anything, its
just like a, placeholder? if I were to input :uninitialized in the
prompt would it still give the .monkey? call though?

···

--
Posted via http://www.ruby-forum.com/\.

Chris Wrote:

> def monkey?( var )
> var != Math::PI && var != "BYE"
> end
So let me get this one straight. Doing it like this would mean that
instead of calling monkey? on the variable i would call the variable on
the monkey? method.? I'm sorry, I did not truly understand the
difference in there would it not be the exact same thing?

Not really. In this example monkey? is a function which takes a single
argument, var. It checks to see if this argument (var) is equal to pi.

In your version, the function monkey? is being added to the String class
itself, which then checks whether the string object it is called from
is equal to pi (which it can never be as pi is a number and the string
must be a string).

> later, seeing :uninitialized in all places where you currently have
> Math::PI
> will make a lot more sense.

Hmm. So if i use :uninitialised then it doesnt really mean anything,
its
just like a, placeholder? if I were to input :uninitialized in the
prompt would it still give the .monkey? call though?

Has the tutorial you're following showed you irb yet? It comes with
Ruby, and it's great for seeing how things work. It lets you type Ruby
statements for immediate execution. A quick demonstration of what he
was talking about with symbols:

irb(main):001:0> def monkey? (var)
irb(main):002:1> var==:noinit
irb(main):003:1> end
=> nil
##So here I define my function, which simply checks to see if it's
##argument is equal to the :noinit symbol
##the => nil is what was produced by defining this function (def
##never returns anything)
irb(main):004:0> monkey? :noinit
=> true
##Call monkey? On the :noinit symbol itself, sure enough :noinit=:noinit
irb(main):005:0> monkey? ':noinit'
=> false
##Call monkey? On the string ':noinit'. Notice they are not equal
irb(main):006:0> reply=gets.chomp
:noinit
=> ":noinit"
irb(main):007:0> monkey? reply
=> false
##input ":noinit" and try calling monkey? on that. Again not equal.

Symbols are nice tools. When you use a symbol like :noinit, it will
only ever equal the symbol :noinit, nothing else. This all however,
is no doubt jumping the gun, and getting well ahead of your tutorial.
I think your best bet would be to move on, and revisit this example
later to see how you can improve upon it.