Learn to Program, by Chris Pine

On 3/31/06, Jan_K [email protected] wrote:

if, else, elsif, while

end

last_input = input
end

I’m not really understanding what last_input is exactly doing. Looks
like nothing.

I may be reading ahead of you, but it doesn’t look like it.
http://pine.fm/LearnToProgram/?Chapter=06

It’s there to honor this spec:
“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.”

It’s making sure that it exits when you say:
“BYE”, “BYE”, “BYE”

but it won’t exit if you say:
“BYE”, “DOG”, “BYE”, “BYE”

If that’s what you typed, on the third input, last_input would be
“DOG”, so ‘goodbye’ would get reset to ‘1’.

Jan K wrote:

You’re right, I didn’t implement one of the features after reading the
exercise instructions again. Oh well. I’ll do it tomorrow.

But I just ran your solution and it doesn’t work :slight_smile:

I needed 4 BYE’s to get out, not 3.

You’re absolutely right. I should claim that I put the error in
deliberately
so you could debug it, but I didn’t. So the lesson (for me) is: TEST
your
code, Dave!

Here’s the fix:

Great work. You fixed it without making it longer; in fact, you made it
shorter!

Sounds to me like you’ll be fine, but of course you can ask the list
here
any questions you have along the way, we love to help.

Cheers,
Dave

Jan K wrote:

I might continue posting the solutions for the rest of the book if I
decide to keep on reading.

This way I won’t develop any bad habits (because hopefully the
solutions will be scrutinized by at least one other person) and it’ll
help anyone else reading the book who gets stuck. I doubt the author
of the book will ever get around to publishing the “official”
solutions.

I just looked at the book samples at pragprog and was surprised to see
there
are no solutions. That probably means Chris doesn’t intend to do
official
solutions. Ah, well. Your points are all valid, posting solutions is a
good
idea all 'round.

Now, scrutiny and no bad habits. You’ve only made one mistake, but I’ll
point out a couple of things that could be done differently.

puts ‘’

That’s the same as just “puts” by itself, with no parameters.

input = input.to_i - 1

You can avoid going backwards here by moving “input = input + 1” to the
end
of the loop. It often makes things simpler to do the increment at the
end
rather than the beginning of a loop.

if input%4 == 0 || input%400 == 0 && input%100 != 0

Here’s the mistake.

1984 and 2004 are leap years. OK.
1800 and 1900 are not leap years. Not OK - this program lists them as
leap
years.
1600 and 2000 are leap years. OK.

In case this info helps, && binds more closely than ||, so what you’ve
got
is the same as:

if input%4 == 0 || (input%400 == 0 && input%100 != 0)

You should be able to rearrange it to give the correct result for the
1984,
2004, 1800, 1900, 1600 and 2000.

Cheers,
Dave

“Dave B.” [email protected] writes:

something.

But if you ask this group, you can get interactive answers!

Let’s start again with that one. We need a loop counting down from 99.

And therefore, we write in Ruby:

99.downto(1) { |bottles| … }

Christian N. wrote:

Let’s start again with that one. We need a loop counting down from 99.

And therefore, we write in Ruby:

99.downto(1) { |bottles| … }

A good point, Christian, and that syntax is introduced in the very next
chapter after the one we’re doing exercises from. It’s good to be able
to do
things more than one way.

Cheers,
Dave

Here’s the solution to the Leap Years exercise in the same chapter:

(everything looks OK to me)


puts ‘Please enter the starting year’
input = gets.chomp
puts ‘Please enter the ending year’
input2 = gets.chomp
puts ‘’
puts ‘The following are leap years:’

input = input.to_i - 1

while input < input2.to_i
input = input + 1
if input%4 == 0 || input%400 == 0 && input%100 != 0
puts input.to_s
end
end

I might continue posting the solutions for the rest of the book if I
decide to keep on reading.

This way I won’t develop any bad habits (because hopefully the
solutions will be scrutinized by at least one other person) and it’ll
help anyone else reading the book who gets stuck. I doubt the author
of the book will ever get around to publishing the “official”
solutions.

Hello!

To sum the digits of an Integer I have got

class Integer
def sum_digits()
sum = 0
n = self
begin sum += n % 10; n /= 10 end while n > 0
sum
end
end

Is there a more Ruby Way to do this? The above method smells of Java,
doesn’t it?

Thanks, Marcus

On Apr 1, 2006, at 7:22 AM, Marcus Lunzenauer wrote:

end
end

Is there a more Ruby Way to do this? The above method smells of
Java, doesn’t it?

Here is what I thought of when reading this:

class Integer
def sum_digits
to_s.split("").inject(0) { |sum, n| sum + n.to_i }
end
end
=> nil

1234.sum_digits
=> 10

Hope that helps.

James Edward G. II

On Sat, 01 Apr 2006 02:03:13 GMT, “Dave B.” [email protected] wrote:

Crap, I knew I should have fully tested my code.

is the same as:

if input%4 == 0 || (input%400 == 0 && input%100 != 0)

You should be able to rearrange it to give the correct result for the 1984,
2004, 1800, 1900, 1600 and 2000.

Yep.

if input%100 != 0 && input%4 == 0 || input%400 == 0

Fix:


puts ‘Please enter the starting year’
input = gets.chomp
puts ‘Please enter the ending year’
input2 = gets.chomp
puts
puts ‘The following are leap years:’

input = input.to_i

while input <= input2.to_i
if input%100 != 0 && input%4 == 0 || input%400 == 0
puts input.to_s
end
input = input + 1
end

1 line shorter at the expense of readability and performance:


puts ‘Please enter the starting year’
input = gets.chomp
puts ‘Please enter the ending year’
input2 = gets.chomp
puts
puts ‘The following are leap years:’

while input.to_i <= input2.to_i
if input.to_i%100 != 0 && input.to_i%4 == 0 || input.to_i%400 == 0
puts input.to_s
end
input = input.to_i + 1
end

I actually did a little benchmark calculating all the leap years for
the next 100 million years (with output going to nul).

Results:

13:26 minutes for the first one.
14:56 minutes for the second one.

The shorter code was 11.16% slower.

On 1 Apr 2006 07:32:50 -0800, [email protected] wrote:

Cool.

Jan_K wrote:

1984 and 2004 are leap years. OK.
2004, 1800, 1900, 1600 and 2000.
input = gets.chomp
end
puts ‘Please enter the ending year’


I actually did a little benchmark calculating all the leap years for
the next 100 million years (with output going to nul).

Results:

13:26 minutes for the first one.
14:56 minutes for the second one.

The shorter code was 11.16% slower.


puts ‘Please enter the starting year’
input = gets.chomp.to_i # Convert to Integer
puts ‘Please enter the ending year’
input2 = gets.chomp.to_i # Convert to Integer
puts
puts ‘The following are leap years:’

while input <= input2
if inputi % 100 != 0 && input % 4 == 0 || input % 400 == 0
puts input.to_s
end
input = input + 1
end

Logan C. wrote:

num_s = num.to_s
(0…(num_s.length)).inject(0) { |s, i| s += (num_s[i] - ?0) }

require ‘enumerator’
num.to_s.enum_for(:each_byte).inject(0) { |sum, c| sum + c - ?0 }

Or, in Ruby 1.9 (I think):
num.to_s.each_byte.inject(0) { |sum, c| sum + c - ?0 }

Cheers,
Dave

Solution for the 1st exercise in chapter 8:

(I’m skipping the 2nd exercise - just a bunch of busywork)


input = []

while input.last != ‘’
input.push gets.chomp
end

puts input.sort

On Apr 1, 2006, at 9:29 AM, James Edward G. II wrote:

begin sum += n % 10; n /= 10 end while n > 0

class Integer
James Edward G. II

num_s = num.to_s
(0…(num_s.length)).inject(0) { |s, i| s += (num_s[i] - ?0) }

Just to increase confusion and to rely on the properties of ASCII

Jan_K wrote:

Solution for the 1st exercise in chapter 8:

You mean chapter 7.

puts input.sort

Very nice!

For exercise 2, writing a program that does something useful is good
practice, and a sort algorithm’s simple and therefore a good candidate
if you can get into it.

Or you could just write a game (Blackjack’s simple) after you finish
chapter 8.

Cheers,
Dave

On Sun, 02 Apr 2006 03:57:21 GMT, Dave B. [email protected] wrote:

Jan_K wrote:

Solution for the 1st exercise in chapter 8:

You mean chapter 7.

I’m actually reading the book and “Arrays and Iterators” is chapter 8.

The book starts with chapter 1 whereas the online tutorial starts with
chapter 0.

Now that I take a look at both it seems like the book is a cleaned-up
and slightly revised version of the tutorial.

Here’s the end of chapter 8 from the book:

8.3 A Few Things to Try

? Write the program we talked about at the beginning of this chapter,
one that asks us to type as many words as we want (one word
per line, continuing until we just press Enter on an empty line)
and then repeats the words back to us in alphabetical order. Make
sure to test your program thoroughly; for example, does hitting
Enter on an empty line always exit your program? Even on the
first line? And the second? Hint: There?s a lovely array method
that will give you a sorted version of an array: sort. Use it!

? Rewrite your table of contents program on page 35. Start the
program with an array holding all of the information for your table
of contents (chapter names, page numbers, etc.). Then print out
the information from the array in a beautifully formatted table of
contents.

This the end of the same chapter from the online tutorial:

A Few Things to Try

? Write the program we talked about at the very beginning of this
chapter.
Hint: There’s a lovely array method which will give you a sorted
version of an array: sort. Use it!

? Try writing the above program without using the sort method. A large
part of programming is solving problems, so get all the practice you
can!

? Rewrite your Table of Contents program (from the chapter on
methods). Start the program with an array holding all of the
information for your Table of Contents (chapter names, page numbers,
etc.). Then print out the information from the array in a beautifully
formatted Table of Contents.

Some crucially important differences:

From the online tutorial:

languages = [‘English’, ‘German’, ‘Ruby’]

languages.each do |lang|
puts 'I love ’ + lang + ‘!’
puts ‘Don't you?’
end

puts ‘And let's hear it for C++!’
puts ‘…’

From the book:

languages = [’ English’ , ’ Norwegian’ , ’ Ruby’ ]

languages.each do |lang|
puts ’ I love ’ + lang + ’ !’
puts ’ Don' t you?’
end

puts ’ And let' s hear it for Java!’
puts ’ ’

Jan_K wrote:

I feel like beating the shit out of some punching bag somewhere. Is
this a normal reaction when one is trying to learn to program for the
first time?

Yes, that is a typical outward manifestation, or projection, of the
initial programming learning process. And, no, it won’t go away. But
there are a few inner thnings on which one needs to focus, as well. To
wit: start learning to “think outside of the box”, be prepared for your
mind to “play tricks” on you, and don’t fight the fact that virtually
all of the difficulties you will face at first will be “logic errors” in
your own thinking and not some anomally of the computer. Adopting this
attitude will help you maintain calmness and reduce stress. Programming
is mentally hard work. But the reward is well worth it. Plus, we here
in the programming community are available to help you!

Chapter 9, exercise 1 (page 76)

“Fix up the ask method. That ask method I showed you was alright,
but I bet you could do better. Try to clean it up by removing the
variables good_answer and answer. You?ll have to use return to
exit from the loop. (Well, it will get you out of the whole method,
but it will get you out of the loop in the process.) How do you
like the resulting method? I usually try to avoid using return
(personal preference), but I might make an exception here.”

Solution:


def ask question
while true
puts question
reply = gets.chomp.downcase
if reply == ‘yes’
return true
elsif reply == ‘no’
return false
else
puts ‘Please answer “yes” or “no”.’
end
end
end

puts ‘Hello, and thank you for…’
puts
ask ‘Do you like eating tacos?’
ask ‘Do you like eating burritos?’
wets_bed = ask ‘Do you wet the bed?’
ask ‘Do you like eating chimichangas?’
ask ‘Do you like eating sopapillas?’
puts ‘Just a few more questions…’
ask ‘Do you like drinking horchata?’
ask ‘Do you like eating flautas?’
puts
puts ‘DEBRIEFING:’
puts ‘Thank you for…’
puts
puts wets_bed

On Sun, 02 Apr 2006 03:57:21 GMT, Dave B. [email protected] wrote:

Actually, I just flipped through the rest of the book and it starts to
diverge quite a bit from the online tutorial starting with the next
chapter and has 4 additional new chapters.

Here are the table of contents from the book:
http://pragmaticprogrammer.com/titles/fr_ltp/index.html

So if I have any more questions I’ll post the exercise instructions
first.

Thanks for your help so far Dave. I was completely stuck in that Flow
Control chapter and pretty much became content that another attempt at
learning programming has successfully failed (just like the previous
half dozen times). It’s amazing how hard it is to grasp incredibly
fucking simple concepts for the first time.

Thanks a lot! I will try one of your solutions.

Bye, Marcus