Does anyone know where I can find the solutions to the exercises in this book: http://pine.fm/LearnToProgram/ I'm stuck in "Flow Control" chapter, specificailly the "Extend Deaf Grandma" exercise. 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?
on 2006-03-29 23:36
on 2006-03-29 23:45
On 29/03/06, Jan_K <non@none.com> wrote: [snip] > 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? I've been programming for over 20 years and I *still* feel like that sometimes. While I can't say what way is definitively best to deal with it, I tend to take a five or ten minute walk when I get to feeling like that. Often, by time that that's done, I've got a fresh idea for how to approach the problem, or I've thought of something I may be missing. Cheers, kjw
on 2006-03-29 23:54
I recommend dancing. Reading fiction also often works for me. kj is right, I've been programming for almost 15 years now and frustration is a frequent companion.
on 2006-03-29 23:57
On 29 Mar 2006, at 22:33, Jan_K wrote: *snip* > I'm stuck in "Flow Control" chapter, specificailly the "Extend Deaf > Grandma" exercise. > > 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? :) Fancy describing the problem, and seeing if someone's got some thoughts on it? Top programming tip - it's amazing how often trying to explain a problem will suddenly make you realise what the answer is. Curious, but true.
on 2006-03-30 00:00
You could use until or if (or both). You could make a variable the would
count how many times in a row you said "BYE" to grandma, starting at 0
of
cause, and make it add 1 each times and reset it to 0 if you did not say
"BYE".
Here is an example:
counter = 0
Until (counter == 3)
tell_grandma = gets.chomp
if (tell_grandma == "BYE")
counter += 1
end
end
Just find a way to integrate with your current grandma program :)
2006/3/29, Jan_K <non@none.com>:
on 2006-03-30 00:03
forgot to make it set counter to 0 if it wasn't "BYE", but I'm sure you can figure that out using else. 2006/3/29, Jeppe Jakobsen <jeppe88@gmail.com>:
on 2006-03-30 04:41
Sometimes I find myself leaving a problem without trying to analyze it, and then when I come back again, it works. Most of the time, I can't figure out why... I just scratch my head and think "What did I do different _this time_?" The encouraging thing about this is that as you get better, the time between the head scratching gets longer. Another resource you can try Ruby on when you get frustrated with Pine is http://tryruby.hobix.com/ This is interactive and fun, and was written by someone who is certifiably insane. (He wrote Poignant's Guide.) Paul
on 2006-03-30 05:21
On Thu, 30 Mar 2006 07:03:17 +0900, "Jeppe Jakobsen" <jeppe88@gmail.com> wrote: >> Here is an example: >> Just find a way to integrate with your current grandma program :) I can't use "Until" because it wasn't covered in the book so far (even though it seems pretty straightforward what it does). Ditto for "+-" What was covered so far up until this chapter: if, else, elsif, while The first thing I tried was nesting IF's and WHILE's in different combinations without using a variable to track the "BYE"s. I thought that this would be the elegant solution, but really couldn't come up with a way to do it. So then I falled back to my first idea of "use variable to track BYE's." But it looks like I'm not understanding the rules of nesting and when/how a branch finishes and kicks you back to the previous branch. Here's what I had when I gave up: ------------------------------------------ input = gets.chomp number = rand(21) number2 = 0 keep_count = 0 if keep_count != 3 while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' keep_count = 0 input = gets.chomp while input == 'BYE' puts 'HUH?! SPEAK UP, SONNY!' number2 = (keep_count + 1) keep_count = number2 input = gets.chomp end end else puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' end ----------------------------------------- And here's the regular Deaf Grandma solution that I used: ---------------------------------------- input = gets.chomp number = rand(21) if while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' input = gets.chomp end else puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' end ------------------------------------- Thanks.
on 2006-03-30 12:20
Hi Jan, Have you been typing his examples into IRB and running them as you go? I found that technique really useful learning Perl - try variations on the example code until you understand it. Try reading Chapter 6 again with IRB, including the mini exercise in the Looping section. But let's unpack your code while it's here: Jan K wrote: > while > end > input = gets.chomp > end > ------------------------------------- When you start dealing with flow control, you'll find that indenting makes a big difference to how easy it is to read and understand your code. Let's start by indenting your Grandma code: if while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' input = gets.chomp end else puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' end Note in all Chris' examples, "if" and "while" are always followed by a condition. If Ruby expects something, but doesn't get it, it'll wait until the following line. That's what's happening with your if and while. It's the same as this: if (while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' input = gets.chomp end) else .... See, while's condition is "input != 'BYE'", and if's condition is the result of the whole while loop. The result of a while loop is always nil, so the condition is always false, so you get 'NO, NOT SINCE'... That means this section of your program is the same as this: while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' input = gets.chomp end puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' Indenting and putting the condition on the same line as the "if" or "while" make the flow of your other program a little easier to see, too. if keep_count != 3 while input != 'BYE' puts 'HUH?! SPEAK UP, SONNY!' keep_count = 0 input = gets.chomp while input == 'BYE' puts 'HUH?! SPEAK UP, SONNY!' number2 = (keep_count + 1) keep_count = number2 input = gets.chomp end end else puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' end Note you've got a loop inside a loop. To get out of that, the inside loop has to exit, and then the outside loop, and if you look at their respective conditions (input == 'BYE') and (input != 'BYE'), that will never happen. Try going back to the example in the Looping section, and modifying that little bits at a time. Indent lines inside control structures to help you see at a glance where they begin and end. Cheers, Dave
on 2006-03-30 16:16
kj WOOLLEY wrote: > idea for how to approach the problem, or I've thought of something I > may be missing. Good advice. See also the Programming and Development episodes of Ward's "EPISODES: A Pattern Language of Competitive Development" available at http://c2.com/ppr/titles.html and the episode failure notes from his Seattle XP talk: http://www.seapig.org/WardCunningham Regards,
on 2006-03-30 17:48
kj WOOLLEY wrote: > On 29/03/06, Jan_K <non@none.com> wrote: > [snip] >> 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? > > I've been programming for over 20 years and I *still* feel like that > sometimes. While I can't say what way is definitively best to deal > with it, I tend to take a five or ten minute walk when I get to > feeling like that. Often, by time that that's done, I've got a fresh > idea for how to approach the problem, or I've thought of something I > may be missing. Well, might I say that he's picked a good language to try out. With other languages, it would be much, much worse. :) A major reason I moved to Ruby is because it vastly reduces (or sometimes eliminates) frustration while programming. Something [I] frequently encountered with other languages (C, C++ (esp. Windows stuff), Java, Perl, Tcl). Pistos
on 2006-03-30 23:40
On Thu, 30 Mar 2006 10:17:55 GMT, "Dave Burt" <dave@burt.id.au> wrote: <snip> >When you start dealing with flow control, you'll find that indenting makes a >big difference to how easy it is to read and understand your code. It is indented. Must be your client. Try this: Tools --> Options --> Read tab Check "Read all messages in plain text" <snip> >Note you've got a loop inside a loop. To get out of that, the inside loop >has to exit, and then the outside loop, and if you look at their respective >conditions (input == 'BYE') and (input != 'BYE'), that will never happen. <snip> The problem was that I didn't realize that I messed up the first Grandma program (which reinforced some misconceptions because the program was working ok). Then I sort of got this idea that I had to use a loop inside a loop and really couldn't get out of that box. Everything is obvious now. Agony of defeat, ecstacy of success. Anyway, here's the final program: (hopefully I don't have any superfluous code this time around) ----------------------------------------------------------------- number = rand(21) number2 = 0 keep_count = 0 while keep_count != 3 input = gets.chomp if input != 'BYE' keep_count = 0 puts 'HUH?! SPEAK UP, SONNY!' else number2 = (keep_count + 1) keep_count = number2 if keep_count != 3 puts 'HUH?! SPEAK UP, SONNY!' end end end puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!'
on 2006-03-31 00:56
Jan K wrote: > It is indented. Must be your client. Wow, my client's not displaying tabs. That really kinda sucks. Thanks for the heads-up! > The problem was that I didn't realize that I messed up the first > Grandma program (which reinforced some misconceptions because the > program was working ok). Then I sort of got this idea that I had to > use a loop inside a loop and really couldn't get out of that box. > > Everything is obvious now. > > Agony of defeat, ecstacy of success. Yay! Once you've got Flow Control, now you can write programs to do real-life useful tasks! > Anyway, here's the final program: > > (hopefully I don't have any superfluous code this time around) That might be a little much to expect this early in the game :-) > else > number2 = (keep_count + 1) > keep_count = number2 > if keep_count != 3 > puts 'HUH?! SPEAK UP, SONNY!' > end > end > end > > puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' > ----------------------------------------------------------------- The line is "number2 = 0" is superfluous, because the first thing you do is assign to it, but it does serve to make it obvious to the programmer the variable exists. If it was my program, though, I'd drop the variables "number" and "number2", and just use the formula directly place - they're only used once each. Like this: keep_count = keep_count + 1 And like this: puts 'NO, NOT SINCE ' + (1930 + rand(21)).to_s + '!' Note you don't need parentheses around the formula on the right-hand side of an assignment: + is done before =. Finally, I prefer not to use the negative "if x != y then foo else bar" because I find easier to understand "if x == y then bar else foo". Another alternative is to use "unless", which Chris seems not to have introduced in Chapter 6, but it means "if not". Same for while - "while keep_count != 3" is the same as "until keep_count == 3". So here are my changes to your program all together: keep_count = 0 until keep_count == 3 input = gets.chomp if input == 'BYE' keep_count = keep_count + 1 unless keep_count == 3 puts 'HUH?! SPEAK UP, SONNY!' end else keep_count = 0 puts 'HUH?! SPEAK UP, SONNY!' end end puts 'NO, NOT SINCE ' + (1930 + number).to_s + '!' But, my understanding of the question must be different to yours. I understand the original should behave like this: > Hello Grandma HUH?! SPEAK UP, SONNY! > HELLO GRANDMA NO, NOT SINCE 1938! > WHAT HASN'T BEEN SINCE 1938? NO, NOT SINCE 1945! > BYE BYE, BYE And the 3-times one should be something like: > Hello Grandma HUH?! SPEAK UP, SONNY! > HELLO GRANDMA NO, NOT SINCE 1938! > BYE HUH?! SPEAK UP, SONNY! > BYE HUH?! SPEAK UP, SONNY! > BYE BYE, BYE I've written my solutions to these after some whitespace at the end of this message. Cheers, Dave # Deaf Grandma input = gets.chomp until input == "BYE" if input == input.upcase puts "NO, NOT SINCE " + (1930 + rand(21)).to_s + "!" else puts "HUH!? SPEAK UP, SONNY!" end input = gets.chomp end puts "BYE, BYE" # Extra Deaf Grandma byes = 0 input = gets.chomp until byes == 3 if input == "BYE" byes = byes + 1 else byes = 0 end if input == input.upcase puts "NO, NOT SINCE " + (1930 + rand(21)).to_s + "!" else puts "HUH!? SPEAK UP, SONNY!" end input = gets.chomp end puts "BYE, BYE"
on 2006-03-31 07:40
Jan_K wrote: > Does anyone know where I can find the solutions to the exercises in > this book: > > http://pine.fm/LearnToProgram/ > > > I'm stuck in "Flow Control" chapter, specificailly the "Extend Deaf > Grandma" exercise. I'm stuck trying to do the part to make it do '99 bottles of beer on the wall' song. I get started in what I hope will work and next thing I know I have way too many variables and nothing makes sense. I even did something that made it loop the integer 0. I had to Ctrl-c on that one. <sigh> Here's what I quit trying at, because no matter how many breaks I took or whatever, it just wasn't making any sense. : puts '99 bottles of beer on the wall, 99 bottles of beer,' 'take one down, pass it around,' '98 bottles of beer on the wall!' song = '99 bottles of beer on the wall, 99 bottles of beer, take one down, pass it around,' song = 99 song2 = '98 bottles of beer on the wall!' song2 = 99 - 1 last = '1 bottle of beer on the wall' last = 1 if song2 == last puts 'Yay!' else if song2 - 1 puts while song == 1 end endputs '99 bottles of beer on the wall, 99 bottles of beer,' 'take one down, pass it around,' '98 bottles of beer on the wall!' song = '99 bottles of beer on the wall, 99 bottles of beer, take one down, pass it around,' song = 99 song2 = '98 bottles of beer on the wall!' song2 = 99 - 1 last = '1 bottle of beer on the wall' last = 1 if song2 == last puts 'Yay!' else if song2 - 1 puts while song == 1 end end I too wish the author had put examples, say on some pages in the back or something.
on 2006-03-31 14:59
JB wrote: > I'm stuck trying to do the part to make it do '99 bottles of beer on the > wall' song. I get started in what I hope will work and next thing I know I > have way too many variables and nothing makes sense. I even did something > that made it loop the integer 0. I had to Ctrl-c on that one. <sigh> > > Here's what I quit trying at, because no matter how many breaks I took or > whatever, it just wasn't making any sense. : > ... > I too wish the author had put examples, say on some pages in the back or > 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. So first, we need a counter. beer = 99 Now, we need to count it down. beer = beer - 1 But we need to do that repeatedly - it goes in a loop. beer = 99 while (something to end the loop?) beer = beer - 1 end How long should we keep looping? We don't want to go past zero. In other words, we loop while our counter is zero or more. beer = 99 while beer >= 0 beer = beer - 1 end OK, now we've got the basic structure of the program - one loop, beer starts at 99, and decreases until it gets to 0. But there's no output yet. See how you go putting some flesh on that skeleton, JB - post back when you're done. (I found learning to program it was better to write than read, so put aside Herr Froelich's solution and make your own!) Cheers, Dave
on 2006-03-31 17:24
On Thu, 30 Mar 2006 22:53:30 GMT, "Dave Burt" <dave@burt.id.au> 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 :) >Hello Grandma HUH!? SPEAK UP, SONNY! >HELLO GRANDMA NO, NOT SINCE 1938! >BYE NO, NOT SINCE 1941! >BYE NO, NOT SINCE 1945! >BYE NO, NOT SINCE 1941! >BYE BYE, BYE I needed 4 BYE's to get out, not 3.
on 2006-03-31 19:11
On 3/29/06, Jan_K <non@none.com> wrote: [snip] > I can't use "Until" because it wasn't covered in the book so far (even > though it seems pretty straightforward what it does). Ditto for "+-" > > What was covered so far up until this chapter: > > if, else, elsif, while > Here's a very simplified example that I believe uses only what's been covered up to that point. last_input = '' goodbye = 1 while goodbye < 3 input = gets.chomp if input == input.upcase puts "NO, NOT SINCE " + (1930 + rand(21)).to_s else puts "HUH?! SPEAK UP, SONNY!" end if input == 'BYE' and last_input == 'BYE' goodbye = goodbye + 1 else goodbye = 1 end last_input = input end
on 2006-03-31 19:54
On Sat, 1 Apr 2006 02:08:40 +0900, "Bill Guindon" <agorilla@gmail.com> wrote: >Here's a very simplified example that I believe uses only what's been > else >end I'm not really understanding what last_input is exactly doing. Looks like nothing. This works without any problems: goodbye = 1 while goodbye < 4 input = gets.chomp if input == input.upcase puts "NO, NOT SINCE " + (1930 + rand(21)).to_s else puts "HUH?! SPEAK UP, SONNY!" end if input == 'BYE' goodbye = goodbye + 1 else goodbye = 1 end end
on 2006-03-31 19:57
On Fri, 31 Mar 2006 10:22:03 -0500, Jan_K <non@none.com> wrote: >>HELLO GRANDMA > >I needed 4 BYE's to get out, not 3. Here's the fix: byes = 0 until byes == 3 input = gets.chomp if input == "BYE" byes = byes + 1 else byes = 0 end if input == input.upcase puts "NO, NOT SINCE " + (1930 + rand(21)).to_s + "!" else puts "HUH!? SPEAK UP, SONNY!" end end puts "BYE, BYE"
on 2006-03-31 20:09
On 3/31/06, Jan_K <non@none.com> 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'.
on 2006-03-31 21:02
Benjohn Barnes wrote: > Top programming tip - it's amazing how often trying > to explain a problem will suddenly make you realise what the answer > is. Curious, but true. This is incredibly true. I often will describe my programming problems to non-programmers who would have essentially no chance of helping me, but end up doing so just by listening. An interesting anecdote: I've been told that there is (or used to be) a rule at the MIT programming help desk that before you could talk to any of the techs, you had to fully describe your problem to a stuffed animal called the "problem bear". It turned out that more than half of the people's problems were solved by the bear.
on 2006-03-31 23:56
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.
on 2006-04-01 03:29
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 :) >... >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
on 2006-04-01 04:05
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
on 2006-04-01 12:08
"Dave Burt" <dave@burt.id.au> 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| ... }
on 2006-04-01 15:05
Christian Neukirchen 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
on 2006-04-01 15:23
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 2006-04-01 16:31
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 Gray II
on 2006-04-01 16:46
On Sat, 01 Apr 2006 02:03:13 GMT, "Dave Burt" <dave@burt.id.au> wrote: Crap, I knew I should have fully tested my code. <snip> >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 2006-04-01 17:36
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
on 2006-04-02 01:52
On Apr 1, 2006, at 9:29 AM, James Edward Gray II wrote: >> begin sum += n % 10; n /= 10 end while n > 0 > >> class Integer > James Edward Gray 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
on 2006-04-02 02:20
Logan Capaldo 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
on 2006-04-02 04:16
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 2006-04-02 05:59
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 2006-04-02 06:18
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!
on 2006-04-02 15:30
On Sun, 02 Apr 2006 03:57:21 GMT, Dave Burt <dave@burt.id.au> 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 ' <crickets chirp in the distance>'
on 2006-04-02 16:35
On Sun, 02 Apr 2006 03:57:21 GMT, Dave Burt <dave@burt.id.au> 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.
on 2006-04-03 02:11
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 2006-04-03 13:42
Just one more way, since I haven't seen a solution that takes advantage
of the no-parameter inject call:
1234.to_s.split('').map {|c| c.to_i }.inject {|i,j| i+j }
=> 10
on 2006-04-03 14:01
Jan_K wrote: > So if I have any more questions I'll post the exercise instructions > first. Good idea; it's sure to avoid further confusion, and I'm sure Mr. Pine wouldn't mind this kind of use of his text. > 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. You're more than welcome. I'm chuffed that you say this, and very glad to have helped. I love teaching programming. I learnt the basics of programming QBasic in a day, back in grade 6, from a friend (probably a little less than the equivalent of what you're up to now). And it is difficult and strange, new vocabulary, "strings", "methods", but it's so useful once you've got it. A lot of repetitive tasks can be reduced to a brain exercise by automating them. (See thread, "Does Ruby simplify our tasks and lives?") And knowing some of these things help you understand computers (and bend them to your every whim bwahahaha... oh, you're still reading?) But mostly it's just fun. Cheers, Dave
on 2006-04-03 14:35
Jan_K wrote:
> Chapter 9, exercise 1 (page 76)
> ...
Perfect. I can't see any problems at all.
Let me add something, though. Instead of chomping the string, you can
strip it. String#strip removes all whitespace from the beginning and end
of the string, rather than just a single \n from the end.
Cheers,
Dave
on 2006-04-03 20:26
Chapter 9, exercise 2 (page 76)
Old-school Roman numerals. In the early days of Roman numerals,
the Romans didn?t bother with any of this new-fangled subtraction
IX nonsense. No sir, it was straight addition, biggest to littlest -
so 9 was written VIIII, and so on. Write a method that, when
passed an integer between 1 and 3000 (or so), returns a string
containing the proper old-school Roman numeral. In other words,
old_roman_numeral 4 should return 'IIII'. Make sure to test
your method on a bunch of different numbers. Hint: Use the integer
division and modulus methods on page 36.
For reference, these are the values of the letters used:
I = 1 V = 5 X = 10 L = 50
C = 100 D = 500 M = 1000
Solution:
----------------------------------------------------------------
def old_roman_number input
while input < 1 || input > 3999
puts 'Please enter a number between 1 and 3999'
input = gets.chomp.to_i
end
m_mod = input%1000
d_mod = input%500
c_mod = input%100
l_mod = input%50
x_mod = input%10
v_mod = input%5
m_div = input/1000
d_div = m_mod/500
c_div = d_mod/100
l_div = c_mod/50
x_div = l_mod/10
v_div = x_mod/5
i_div = v_mod/1
m = 'M' * m_div
d = 'D' * d_div
c = 'C' * c_div
l = 'L' * l_div
x = 'X' * x_div
v = 'V' * v_div
i = 'I' * i_div
puts m + d + c + l + x + v + i
end
number = gets.chomp.to_i
old_roman_number(number)
on 2006-04-03 20:44
Chapter 9, exercise 3 (page 76)
Modern Roman numerals. Eventually, someone thought it would
be terribly clever if putting a smaller number before a larger one
meant you had to subtract the smaller one. As a result of this
development, you must now suffer. Rewrite your previous method
to return the new-style Roman numerals, so when someone calls
roman_numeral 4, it should return 'IV'.
Solution:
----------------------------------------------------------------
def roman_numeral input
while input < 1 || input > 3999
puts 'Please enter a number between 1 and 3999'
input = gets.chomp.to_i
end
m_mod = input%1000
d_mod = input%500
c_mod = input%100
l_mod = input%50
x_mod = input%10
v_mod = input%5
m_div = input/1000
d_div = m_mod/500
c_div = d_mod/100
l_div = c_mod/50
x_div = l_mod/10
v_div = x_mod/5
i_div = v_mod/1
m = 'M' * m_div
d = 'D' * d_div
c = 'C' * c_div
l = 'L' * l_div
x = 'X' * x_div
v = 'V' * v_div
i = 'I' * i_div
if i == 'IIII' && v != 'V'
i = 'IV'
elsif i == 'IIII'
v = 'IX'
i = ''
end
if x == 'XXXX' && l != 'L'
x = 'XL'
elsif x == 'XXXX'
l = 'XC'
x = ''
end
if c == 'CCCC' && d != 'D'
c = 'CD'
elsif c == 'CCCC'
d = 'CM'
c = ''
end
puts m + d + c + l + x + v + i
end
number = gets.chomp.to_i
roman_numeral(number)
on 2006-04-29 20:38
Hello,
thank you very much for all these good answers
(especially to Jan_K and Dave Burt ).
Im learning ruby with the same book and get stuck
in chapter 10.2 Rite of Passage:Sorting
this exercise is about array sort algorithms.
Instead of 'array.sort' i have to program my own sort method.
chris pine gives a few hints:
using < to find the smallest word in a list
take two lists in the method
and these two empty methods
def sort some_array
recursive_sort some_array, []
end
def recursive_sort unsorted_array, sorted_array
end
After a lot of trying and searching ...
...I found the quicksort algorithm and this code
def quicksort( array )
if array.size <= 1
array
else
ls, rest = array.partition { |i| i < array[0] }
puts 'ls:'+ls.to_s
puts 'rest:'+rest.to_s
rs, rest = rest.partition { |i| i > array[0] }
puts 'rs:'+rs.to_s
puts 'rest2:'+rest.to_s
quicksort( ls ) + rest + quicksort( rs )
end
end
Yes this is a possible solution, but array.partion ,double
assignments(ls,rest)
of variables,arrays and the 'short block' (like { |i| i > array[0] })
are not mentioned in any chapter before.
Although I understand the Code above , I'm looking for an easy solution
that don't leave the scope of chaper 1 to 10 .
Here's my own code, but it doesn't work .
def ownsort unsort, sort
rest=[]
rs=[]
if unsort.size <= 1
unsort
else
unsort.each do |i|
if i <unsort[0]
sort.push i
else
rest.push i
end
end
end
rest
end
thanks for reading and hopefully some hints...
colin
on 2006-05-03 19:09
I'm not quite sure there are solutions. However, as a fellow beginning programmer, I would enjoy discussing our solutions since I finished that book only one week ago. Cheers, Marco
on 2006-05-03 19:09
Restricting to what is covered in chapters 1-10, how about the
following?
def sort some_array
recursive_sort some_array, []
end
def recursive_sort unsorted_array, sorted_array
if unsorted_array.size == 0
return sorted_array
else
smallest = unsorted_array[0]
unsorted_array.each do |x|
if x < smallest
smallest = x
end
end
new_unsorted_array = []
unsorted_array.each do |x|
if x == smallest
sorted_array.push(x)
else
new_unsorted_array.push(x)
end
end
recursive_sort new_unsorted_array, sorted_array
end
end
on 2006-05-03 19:09
> On Thursday, March 30, 2006, at 6:33 AM, 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? Not exactly, but I suppose it depends on the person. Perhaps you need to take a page out of the carpenters handbook and walk away for a while, then come back to the problem. >> Jan -- Jeremy Tregunna jtregunna@blurgle.ca "You cannot depend on your eyes, when your imagination is out of focus." -- Mark Twain
on 2006-05-04 12:30
Jeff de Vries wrote: > Restricting to what is covered in chapters 1-10, how about the > following? Thank you Jeff, Your Code looks great and I think it is exactly what I'm looking for. Next I will try to answer your question about the Restriction. The first ten chapters of the book covers only a few array methods like each,join,last,length,pop. no partition, no selection or double assignment. Futhermore we have if -else,elsif- end, do-end,while-end,puts, gets (with chomp,downcase),array=[],times(3.times do...) we have basics like numbers and strings ,variables assignment, comparison methods (==,!=,<,>...),writing own methods (def- end) In Chapter 11-14 the author talks about: reading and writing files, creating classes,YAML,Blocks and Procs and a hint to other learning resources like Programming Ruby or this mailing-list... The book is a great starting point with many exercises. It is great to learn programming. It's explains Basic 'Thinking-Skills' of programming and how ruby works. The author provides only one way to do something. This limitation is great. I have no problems with the excercises until chapter 10. And Chapter 11 should be not so hard to understand (hopefully...) BTW: The book is the extended Version of this Tutorial: http://pine.fm/LearnToProgram/ greetings Colin
on 2006-08-22 16:03
For interest, before I bought the book I did this exercise for the
online tuorial. That was before I knew about recursives, here is what
I came up with... it works, but it's not pretty
words_array = []
puts 'Please enter any word'
word = gets.chomp
while word != ''
words_array.push word
puts 'Great, please enter another word'
word = gets.chomp
end
sorted_array = []
words_array.each do |word|
if word.to_s.downcase > sorted_array.last.to_s.downcase
#add word to the end of sorted_array
sorted_array.push word
else
index = (sorted_array.length) - 1
initial_number = index
temp_array = []
#check word against next word in sorted_array and repeat
while word.to_s.downcase < sorted_array[index].to_s.downcase
#add the sorted_array to a temp_array up to that point
temp_array[index] = sorted_array[index]
#erase words in sorted_array up to that point
sorted_array.pop
index = index - 1
end
#add the word to sorted_array
sorted_array.push word
#add one by one the words from temp_array to sorted_array
while index < initial_number
sorted_array.push temp_array[index + 1]
index = index + 1
end
end
end
puts sorted_array
on 2006-10-09 04:46
I'm having some issues modifying the Civ continent example from ch. 10
to account for coordinates that are outside the array. I added the
following line:
if ((y <= 10 && y > 0) && (x <= 10 && x > 0))
before...
# So, first we count this tile...
size = 1
world[y][x] = 'counted land'
# ...then we count all of the
# neighboring eigth tiles (and,
# of course, their neighbors via recursion)
size = size + continent_size(world, x-1, y-1) #4,4
size = size + continent_size(world, x , y-1) #5,4
size = size + continent_size(world, x+1, y-1) #6,4
size = size + continent_size(world, x-1, y ) #4,5
size = size + continent_size(world, x+1, y ) #6,5
size = size + continent_size(world, x-1, y+1) #4,6
size = size + continent_size(world, x , y+1) #5,6
size = size + continent_size(world, x+1, y+1) #6,6
size
end
As a result, I get the following error:
TypeError: nil can't be coerced into Fixnum
method + in civilization.rb at line 35
method continent_size in civilization.rb at line 35
method continent_size in civilization.rb at line 35
method continent_size in civilization.rb at line 36
method continent_size in civilization.rb at line 35
method continent_size in civilization.rb at line 40
method continent_size in civilization.rb at line 39
method continent_size in civilization.rb at line 41
method continent_size in civilization.rb at line 39
method continent_size in civilization.rb at line 41
method continent_size in civilization.rb at line 39
method continent_size in civilization.rb at line 36
method continent_size in civilization.rb at line 35
at top level in civilization.rb at line 48
This error appears regardless of whether the arguments I pass are in 5,5
(as in the example Chris Pine wrote out) or something like 10,10 (which
is on the edge of the 'continent').
Is that the right conditional statement? Could it be in the wrong place
in the method?
on 2006-10-09 21:02
Hi Mike, I don't know the book and that is probably true for a lot of the people here. Maybe you should include the full source code. Especially interesting would be to see the line numbers as the interpreter clearly indicates where the problem occurs. As a totally wild guess ... The error message says that the right side of an addition is nil. So looking at your code, "size" seems to be set, maybe continent_size does return nil? What I also think is strange is that "world" seems to be a two dimensional array when you first mention it (world[x][y] = 'counted land'), but later on you pass it to continent size along with two parameters. This might be ok, if continent_size defines three parameters, like this: def continent_size(world, x, y); end and you use x and y to access the array then?! I don't know about the conditional. What are you trying to check? That both x and y are between 1 and 10? That should work ... Even though you wouldn't need the braces as it all of the conditionals need to be true for the whole expression to become true. This would be different if you use "or". Hope that helps! Cheers, Mariano
on 2006-10-10 04:32
here's the whole code...
# These are just to make the map easier to read. "M" is
# visually more dense than "o".
M = 'land'
o = 'water'
world = [[M,o,o,o,o,o,o,o,o,o,M],
[o,M,M,o,M,M,o,o,o,M,M],
[o,o,M,M,o,o,o,o,M,M,o],
[o,o,o,M,o,o,o,o,o,M,o],
[o,o,o,M,o,M,M,o,o,o,o],
[o,o,o,o,M,M,M,M,o,o,o],
[o,o,o,M,M,M,M,M,M,M,o],
[o,o,o,M,M,o,M,M,M,o,o],
[o,o,M,M,o,o,M,M,M,o,o],
[o,M,M,M,o,M,o,o,o,M,M],
[M,o,o,o,o,o,o,o,o,o,M]]
def continent_size world, x, y
if world[y][x] != 'land'
# either it's water or we've already counted it; we don't want to
count it
# again
return 0
end
if ((y <= 10 && y > 0) && (x <= 10 && x > 0))
# So, first we count this tile...
size = 1
world[y][x] = 'counted land'
# ...then we count all of the
# neighboring eigth tiles (and,
# of course, their neighbors via recursion)
size = size + continent_size(world, x-1, y-1)
size = size + continent_size(world, x , y-1)
size = size + continent_size(world, x+1, y-1)
size = size + continent_size(world, x-1, y )
size = size + continent_size(world, x+1, y )
size = size + continent_size(world, x-1, y+1)
size = size + continent_size(world, x , y+1)
size = size + continent_size(world, x+1, y+1)
size
end
end
puts continent_size(world, 5, 5) #this should be fine; but what about
(11,11)?
on 2006-10-10 08:43
Hi Mike,
what your guard should do is prevent the recursion go across the
boundaries of your world, right?
I would put the guard at the beginning of the method to make sure
that the rest of the method can be sure of handling valid data.
if x < 0 || x > 10 || y < 0 || y > 10
return 0 # respect the world's boundaries
end
> def continent_size world, x, y
> if world[y][x] != 'land'
> # either it's water or we've already counted it; we don't want to
> count it
> # again
> return 0
> end
That's a bit of a problem as your code might already call with out of
bounds coordinates.
Put the boundary guard (see above) before that.
> if ((y <= 10 && y > 0) && (x <= 10 && x > 0))
An array starts to count at zero ... so it needs to be (y <= 10 && y
>= 0), right?
You have eleven columns and eleven rows. So the array indices are 0..10.
> size = size + continent_size(world, x+1, y-1)
> size = size + continent_size(world, x-1, y )
> size = size + continent_size(world, x+1, y )
> size = size + continent_size(world, x-1, y+1)
> size = size + continent_size(world, x , y+1)
> size = size + continent_size(world, x+1, y+1)
> size
Ok, you're returning the size here, but
> end
what are you returning here, if you haven't been in this if-block?
nil. That is a major part of your problem...
> end
Use the code above and put it after the definition of the method.
Remove your own "if" and your method should work.
> puts continent_size(world, 5, 5) #this should be fine; but what about
> (11,11)?
That's up to you. In my code (the guard) it returns 0. So that 11,11
will return 0.
You could also raise an exception that the coordinates are out-of-
bounds, but I guess that will come later in your book and is not that
straight forward applicable here.
Cheers,
Mariano
on 2006-10-15 06:51
He Fa: Good Job! However, I don't fully understand how this worked. > words_array.each do |word| > if word.to_s.downcase > sorted_array.last.to_s.downcase > #add word to the end of sorted_array > sorted_array.push word > > else > index = (sorted_array.length) - 1 > initial_number = index > temp_array = [] The second WHILE section was where I got really confused. > #check word against next word in sorted_array and repeat > while word.to_s.downcase < sorted_array[index].to_s.downcase > #add the sorted_array to a temp_array up to that point > temp_array[index] = sorted_array[index] > #erase words in sorted_array up to that point > sorted_array.pop > index = index - 1 > end > > #add the word to sorted_array > sorted_array.push word > > #add one by one the words from temp_array to sorted_array > while index < initial_number > sorted_array.push temp_array[index + 1] > index = index + 1 > end > end > end > > puts sorted_array I've been wrapping my head around my own version of the non-recursive sort for days and haven't made it work.
on 2007-06-13 23:04
Hello all. Thanks to all the posters who came before me! You've been tremendous help. I have a quick question on Chapter 11 - Reading and Writing, Section 11.3: <quote> file_name = 'TestFile.txt' test_string = 'Nothing!' File.open file_name, 'w' do |f| f.write test_string end read_string = File.read file_name puts(read_string == test_string) </quote> I poked around the web, but I can't find out what the 'w' is for. Can anyone shed any light? Muchas gracias in advance. -Todd
on 2007-06-13 23:10
> > </quote> > > I poked around the web, but I can't find out what the 'w' is > for. Can anyone shed any light? Muchas gracias in advance. http://dev.rubycentral.com/ref/ref_c_file.html#open the 'w' option opens the file for writing. - donald
on 2007-06-13 23:15
On 6/13/07, Tm Bo <vineire77@gmail.com> wrote: > end > > read_string = File.read file_name > puts(read_string == test_string) > </quote> > > I poked around the web, but I can't find out what the 'w' is for. Can > anyone shed any light? Muchas gracias in advance. It's the file 'mode'. w = write. http://www.zenspider.com/Languages/Ruby/QuickRef.html#15
on 2007-06-13 23:15
On Thu, Jun 14, 2007 at 06:04:25AM +0900, Tm Bo wrote: > end > > read_string = File.read file_name > puts(read_string == test_string) > </quote> > > I poked around the web, but I can't find out what the 'w' is for. Can > anyone shed any light? Muchas gracias in advance. Check out this page: http://www.rubycentral.com/book/ref_c_file.html Looking at it, I see that File.open is sometimes a synonym for File.new, so I checked File.new, and that's where I found documentation of the use of characters in that position in the method call. The w itself basically means "write". It refers to how you open the file (for reading, writing, or both). Hopefully this gives you a helpful start on figuring out the rest of the details of how File.new and File.open work. I was surprised to find that File.open isn't in my local ri database, though.
on 2007-06-14 16:16
Probably because it makes more sense to people new to Ruby when the code is in a more traditional format; i.e. File.open(file_name, 'w') Personally the openess of Ruby cased problems for me when I first moved over (and still does sometimes). I love the fact that you can do things many different ways in ruby, but when you're trying to learn the language and you're given 10 different options with 10 different explanations it becomes much more confusing than only having 1 or 2 ways. :(
on 2007-06-14 16:24
On Jun 13, 2007, at 4:16 PM, Tm Bo wrote: > Thanks, donald. I don't know why I missed that before. > > -- > Posted via http://www.ruby-forum.com/. > You will do well to make notes on File and read/write modes! The basic implementation of this kind of thing is almost the same in many lanugages, Ruby's is no exception, the style of this comes straight from C . You will see it in PHP too, and a host of other languages.. (all C's children and relatives.) Some books fail to document this stuff well for beginners. they either don't want to go there yet, or they forget about it since they assume you know it from other languages. Mr. Pine just isn't going there in his book. He's focusing on other subjects
on 2008-02-02 20:33
This is my take on the same problem:
def roman_num number
set1 = [ 1, 5, 10, 50, 100, 500, 1000 ]
set2 = [ 'I', 'V', 'X', 'L', 'C', 'D', 'M' ]
numeral = []
while number > 0
if (number/(set1.last)) >= 1
roman = (number/(set1.last))
numeral.push((set2.pop)*roman)
number = (number%(set1.pop))
else
set2.pop
set1.pop
end
end
puts 'Old Roman Numeral is ' + numeral.join + '.'
end
puts 'Please enter a number to see what it is in old roman numerals.'
number = gets.chomp.to_i
while number < 1 || number > 3999
puts 'Please enter a number between 1 and 3999'
number = gets.chomp.to_i
end
roman_num number
Jan_K wrote:
> Chapter 9, exercise 2 (page 76)
>
> Old-school Roman numerals. In the early days of Roman numerals,
> the Romans didn?t bother with any of this new-fangled subtraction
> IX nonsense. No sir, it was straight addition, biggest to littlest -
> so 9 was written VIIII, and so on. Write a method that, when
> passed an integer between 1 and 3000 (or so), returns a string
> containing the proper old-school Roman numeral. In other words,
> old_roman_numeral 4 should return 'IIII'. Make sure to test
> your method on a bunch of different numbers. Hint: Use the integer
> division and modulus methods on page 36.
> For reference, these are the values of the letters used:
> I = 1 V = 5 X = 10 L = 50
> C = 100 D = 500 M = 1000
>
>
> Solution:
> ----------------------------------------------------------------
> def old_roman_number input
>
> while input < 1 || input > 3999
> puts 'Please enter a number between 1 and 3999'
> input = gets.chomp.to_i
> end
>
> m_mod = input%1000
> d_mod = input%500
> c_mod = input%100
> l_mod = input%50
> x_mod = input%10
> v_mod = input%5
>
> m_div = input/1000
> d_div = m_mod/500
> c_div = d_mod/100
> l_div = c_mod/50
> x_div = l_mod/10
> v_div = x_mod/5
> i_div = v_mod/1
>
> m = 'M' * m_div
> d = 'D' * d_div
> c = 'C' * c_div
> l = 'L' * l_div
> x = 'X' * x_div
> v = 'V' * v_div
> i = 'I' * i_div
>
> puts m + d + c + l + x + v + i
>
> end
>
> number = gets.chomp.to_i
> old_roman_number(number)
on 2008-02-03 02:47
On Feb 2, 2008 1:33 PM, Kelly Tanguay <kelly.tanguay@cox.net> wrote: > numeral.push((set2.pop)*roman) > number = gets.chomp.to_i > while number < 1 || number > 3999 > puts 'Please enter a number between 1 and 3999' > number = gets.chomp.to_i > end > roman_num number Just for fun. Certainly not great for speed for large numbers, but the integer max was low so... H = Hash[*(([1,5,10,50,100,500,1000].zip %w|I V X L C D M|).flatten)] def roman(n, s="") H.keys.sort.reverse.each do |k| s << (H[k] * (n / k)) n %= k end s end puts roman(ARGV[0].to_i) The usage would simply be "ruby <filename>.rb <number>" I'm sure someone could come up with a one-liner, though. Todd
on 2008-02-03 03:50
On Feb 2, 2008 7:47 PM, Todd Benson <caduceass@gmail.com> wrote: > s > end > puts roman(ARGV[0].to_i) > > The usage would simply be "ruby <filename>.rb <number>" > > I'm sure someone could come up with a one-liner, though. Actually, better production code that keeps in line with OO concepts would be... class Integer ROMAN = { 1 => "I", 5 => "V", 10 => "X", 50 => "L", 100 => "C", 500 => "D", 1000 => "M" } def roman number, roman_string = self, "" ROMAN.keys.sort.reverse.each do |key| roman_string << (ROMAN[n] * (number/key) n %= key end roman_string end end #usage puts 2137.roman # => "MMCCCXVII" I'm pretty sure there were better and more thorough examples at http://www.rubyquiz.com/quiz22.html. Todd
on 2008-02-03 07:03
On Feb 2, 2008 8:49 PM, Todd Benson <caduceass@gmail.com> wrote: > 1000 => "M" > end > > #usage > puts 2137.roman > # => "MMCCCXVII" > > I'm pretty sure there were better and more thorough examples at > http://www.rubyquiz.com/quiz22.html. gsub('number', 'n') on that code...and there's a missing parenthesis ")" number/key line Yeah, yeah That's what I get for not using cut and paste :-) Todd
on 2008-02-03 14:45
BTW a little trick for later, if you i.e. have an array, and find yourself using a counter, you can stop using the counter and instead use array.size and check on that value. I like "Learn to Program" but I never bothered to make the examples. Like with homework in school many years ago - I did this in school. Not at home... :-)
on 2008-02-04 21:19
On Feb 4, 2008 12:20 PM, Moises Trovo <moises.trovo@gmail.com> wrote:
> actually ROMAN[key] and not working with numbers having a 9.
Here's the copy and pasted code...
class Integer
ROMAN = {
1 => "I",
5 => "V",
10 => "X",
50 => "L",
100 => "C",
500 => "D",
1000 => "M"
}
def roman
n, roman_string = self, ""
ROMAN.keys.sort.reverse.each do |key|
roman_string << (ROMAN[key] * (n/key))
n %= key
end
roman_string
end
end
#usage
puts 2319.roman
# => "MMCCCXVIIII"
cheers,
Todd
on 2008-05-28 19:02
Hey everyone I was having a slight problem with one of the examples in
the book. I was doing the '99 beers' example and ran into a problem at
the end. The task asks you to create a prog that will recite the lyrics
for '99 beers on the wall' which seemed fairly easy to do but I wanted
to make it more challenging for myself and make it more grammatically
correct. So I tried to create an if statement to change the word
'bottles' to 'bottle' when bottles = 1. I have seen another example
creating a working solution but requires many more lines of code and I
was trying to do it in a more clever way (maybe it is backfiring). I
just can't figure out why it is not working properly. Anyway here is
the code:
[code]
bottles = 99
bword = ' bottles'
while bottles != 0
puts(bottles.to_s + bword + " of beer on the wall!")
puts(bottles.to_s + bword + " of beer!")
puts("Take one down and pass it around!")
bottles = bottles - 1
puts(bottles.to_s + bword + " of beer on the wall!")
puts ''
if bottles == 1
bword = ' bottle'
else
bword = ' bottles'
end
end
[/code]
and here is the output that isn't showing up as planned:
2 bottles of beer on the wall!
2 bottles of beer!
Take one down and pass it around!
1 bottles of beer on the wall!
1 bottle of beer on the wall!
1 bottle of beer!
Take on down and pass it around!
0 bottle of beer on the wall!
It doesn't work for the first line with a 1 on it and I wanted it to
switch back to 'bottles' with the zero on the last line. Any thoughts?
on 2008-05-28 19:41
On 28 May 2008, at 18:05, Patrick Hummer wrote: > bword = ' bottle' > else > bword = ' bottles' > end > end You need to reorder your logic slightly so that bword is changed as soon as the bottle count is decremented: bottle = 99 bword = 'bottles' while bottles != 0 puts(bottles.to_s + bword + " of beer on the wall!") puts(bottles.to_s + bword + " of beer!") puts("Take one down and pass it around!") bottles = bottles - 1 if bottles == 1 bword = ' bottle' else bword = ' bottles' end puts(bottles.to_s + bword + " of beer on the wall!") puts '' end Ellie Eleanor McHugh Games With Brains http://slides.games-with-brains.net ---- raise ArgumentError unless @reality.responds_to? :reason
on 2012-08-09 09:44
Jan_K wrote in post #55253: > Does anyone know where I can find the solutions to the exercises in > this book: > > http://pine.fm/LearnToProgram/ > > > I'm stuck in "Flow Control" chapter, specificailly the "Extend Deaf > Grandma" exercise. > > 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? Hi: I googled the book and answers and here's where they are: http://learntoprogramanswers.blogspot.com/2008/01/...
on 2012-08-09 20:05
Pine's book is, for it's price, rubbish! You can find better on the web for free. And this applies to most of the Ruby books out there See how many actually create a full program with an interface?
on 2013-01-23 18:41
Hi! I'm newbie and this are my first steps. This is my solution for
Modern Roman numerals using arrays and each.
<!-- Code -->
romans =
[1000,'M'],[900,'CM'],[500,'D'],[400,'CD'],[100,'C'],[90,'XC'],[50,'L'],[40,'XL'],[10,'X'],[9,'IX'],[5,'V'],[4,'IV'],[1,'I']
result = []
puts "Please enter a number"
num = gets.chomp.to_i
print "\n" + num.to_s + " in Modern Roman Numerals is: "
romans.each do |nroman|
number = nroman[0]
letter = nroman[1]
while num >= number
result.push letter
num -= number
end
end
print result.join
<!-- #Code -->
cheers!!
Martin
on 2013-01-23 22:46
On Jan 23, 2013, at 09:41 , Martin Alejandro <lists@ruby-forum.com> wrote: > romans.each do |nroman| > number = nroman[0] > letter = nroman[1] can become: > romans.each do |nroman| > number, letter = nroman can become: > romans.each do | (number, letter) | can become:
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.