header image


November 16th, 2006

, A short time ago in a galaxy not so far, , far away I came across a nice blog post: 15 Exercises for Learning a new Programming Language.

, One could argue if these are *really* the most appropriate 15(+) exercises to learn a new programming language - however, , the task of answering this rather complex question is left as an exercise for the reader. , Instead of this I will show you their implementation in Ruby - rubyrailways.com style.

, Why did I bother to solve these problems (including not really trivial ones, , like a scientific calculator with a GUI) ? Well, , actually to learn a new programming language! I still consider myself a beginner Ruby apprentice just playing it by ear in my somewhat scarce free time, , so I thought that systematically implementing a task list like this will mean great step forward for me compared to just coding random things at random times. , Fortunately I was perfectly right!

, Before we move onto the code, , one last disclaimer: the fact that I am still a Ruby n00b implies that the code can be somewhat hairy/not optimal/[insert any other language than Ruby here]-ish so don’t use these snippets as a textbook solution of the problems or anything like that. , I would be glad if someone could suggest a bit of refactoring of the bad parts but I also hope that that there are some nice parts which you can learn from (actually I am quite sure about this since I used some magick formulas from a few Ruby (grand)masters in some cases).

, OK, , enough talk for now. , Let’s see the stuff!

, 1. , Problem: “Display series of numbers (1, ,2, ,3, ,4, , 5….etc) in an infinite loop. , The program should quit if someone hits a specific key (Say ESCAPE key).”

, Solution: Hmm, , well, , errr…uh-oh… , I could not solve this problem fully (what a terrific start :-)). , If Henry Ford would sit beside me now, , he would say : You can hit any key to exit - so long as it’s ‘C’ - and one more advice: don’t forget to hold CTRL during this action :-). , More on this after the code snippet:

,

  1. i = 0
  2. loop { print "#{i+=1}, , " }

, Comments : If anyone knows how to add code which will cause this program to stop with a specific keyhit (say ‘ESC’) please, , please, , please drop me a note. , I have been researching this for at least 10% of the time of solving all the tasks, , nearly spitting blood when I gave up :-). , It seems (to me) that there is no simple (i.e. , no threads and similar) and clean platform-independent solution for this problem. , I guess (hope) the author’s idea here was different than to introduce threading or writing platform specific-code…

, 2. , Problem: “Fibonacci series, , swapping two variables, , finding maximum/minimum among a list of numbers.”

, Solution:

,

  1. #Fibonacci series
  2. Fib = Hash.new{ |h, , n| n < 2 ? h[n] = n : h[n] = h[n - 1] + h[n - 2] }
  3. puts Fib[50]
  4.  
  5. #Swapping two variables
  6. x, ,y = y, ,x
  7.  
  8. #Finding maximum/minimum among a list of numbers
  9. puts [1, ,2, ,3, ,4, ,5, ,6].max
  10. puts [7, ,8, ,9, ,10, ,11].min

, Comments: The Fibonacci code was written by Andrew Johnson (found via Ruby Quiz). , I like it so much that I think it would be a shame to present a trivial version here. , I guess the rest of the code is self-explanatory.

, 3. , Problem: “Accepting series of numbers, , strings from keyboard and sorting them ascending, , descending order.”

, Solution:

,

  1. a = []
  2. loop { break if (c = gets.chomp) == ‘q’; a << c }
  3. p a.sort
  4. p a.sort { |a, ,b| b<=>a }

, Comments: This version is accepting strings - I think anybody who got to this point can adapt it to work with numbers. ,

, 4. , Problem: “Reynolds number is calculated using formula (D*v*rho)/mu Where D = Diameter, , V= velocity, , rho = density mu = viscosity Write a program that will accept all values in appropriate units (Don’t worry about unit conversion) If number is < 2100, , display Laminar flow, , If it’s between 2100 and 4000 display 'Transient flow' and if more than '4000', , display 'Turbulent Flow' (If, , else, , then...)"

, Solution:

,

  1. vars = %w{D V Rho Mu}
  2.  
  3. vars.each do |var|
  4.   print "#{var} = "
  5.   val = gets
  6.   eval("#{var}=#{val.chomp}")
  7. end
  8.  
  9. reynolds = (D*V*Rho)/Mu.to_f
  10.  
  11. if (reynolds < 2100)
  12.   puts "Laminar Flow"
  13. elsif (reynolds > 4000)
  14.   puts "Turbulent Flow"
  15. else
  16.   puts "Transient Flow"
  17. end

, Comments: Can you spot the trick in the part which is filling up the variables? They don’t go out of scope after the loop ends because they are constants. , Other possibility would be to use $global variables but I guess it is usually not a very good programming practice to do that.

, 5. , Problem: “Modify the above program such that it will ask for ‘Do you want to calculate again (y/n), , if you say ‘y’, , it’ll again ask the parameters. , If ‘n’, , it’ll exit. , (Do while loop) While running the program give value mu = 0. , See what happens. , Does it give ‘DIVIDE BY ZERO’ error? Does it give ‘Segmentation fault..core dump?’. , How to handle this situation. , Is there something built in the language itself? (Exception Handling)”

, Solution:

,

  1. vars = { "d" => nil, , "v" => nil, , "rho" => nil, , "mu" => nil }
  2.  
  3. begin
  4.   vars.keys.each do |var|
  5.     print "#{var} = "
  6.     val = gets
  7.     vars[var] = val.chomp.to_i
  8.   end
  9.  
  10.   reynolds = (vars["d"]*vars["v"]*vars["rho"]) / vars["mu"].to_f
  11.   puts reynolds
  12.  
  13.   if (reynolds < 2100)
  14.     puts "Laminar Flow"
  15.   elsif (reynolds > 4000)
  16.     puts "Turbulent Flow"
  17.   else
  18.     puts "Transient Flow"
  19.   end
  20.  
  21.   print "Do you want to calculate again (y/n)? "
  22. end while gets.chomp != "n"

, Comments: As you can see, , I could not use the same trick here when asking for the variables, , because when somebody wants to calculate again, , Ruby will complain (although by printing a warning only) that the constants have been already set up. , Therefore I went for the hash solution. , I think the do-you-want-to-calculate-again part is straightforward so I won’t analyze that here.
“While running the program give value mu = 0.”
Ruby gives a rather interesting result in this case: infinity :-).
“Is there something built in the language itself?”
Sure: exception handling. , Division by zero could be caught with a ZeroDivisionError rescue clause.

, 6. , Problem: “Scientific calculator supporting addition, , subtraction, , multiplication, , division, , square-root, , square, , cube, , sin, , cos, , tan, , Factorial, , inverse, , modulus”

, Solution:
Since this code snippet is longer It would look ugly here - you can download it from here instead. ,

Screenshot:

screenshot of the scientific calculator in action

, If you would like to try it, , you will need the Tk bindings for Ruby (maybe you have them already, , here on Ubuntu I did not). , Also note that only the regular 0-9 keys (and of course the mouse) work, , the numpad ones do not. , One more little detail: % stands for modulo, , not percent.

, Comments: Phew, , this was a real challenge, , mostly because I never did any GUI in Ruby before. , I was amazed that I could code up a relatively feature rich calculator in 100+ lines of code, , without any golfing or trying to optimize for shortness. , What I wanted to say with this is that the shortness does not praise my programming skills (since I did not eve try to golf) but the superb terseness of Ruby. , OK, , of course there are some problems (e.g. , cube, , cos, , tan, , inverse are not implemented) but the usability/amount of code ratio is unbelievably high.

, The GUI is also not the nicest since I have used Tk - wxRuby or qt-ruby would produce much nicer results, , but since I did not code any GUI in Ruby previously, , I have decided to try the good-old-skool Tk for the first time.

, 7. , Problem: “Printing output in different formats (say rounding up to 5 decimal places, , truncating after 4 decimal places, , padding zeros to the right and left, , right and left justification)(Input output operations)”

, Solution:

,

  1. #rounding up to 5 decimal pleaces
  2. puts sprintf("%.5f", , 124.567896)
  3.  
  4. #truncating after 4 decimal places
  5. def truncate(number, , places)
  6.   (number * (10 ** places)).floor / (10 ** places).to_f
  7. end
  8.  
  9. puts truncate(124.56789, , 4)
  10.  
  11. #padding zeroes to the left
  12. puts ‘hello’.rjust(10, ,’0)
  13.  
  14. #padding zeroes to the right
  15. puts ‘hello’.ljust(10, ,’0)
  16.  
  17. #right justification
  18. puts ">>#{’hello’.rjust(20)}<<"
  19.  
  20. #left justification
  21. puts ">>#{’hello’.ljust(20)}<<"

, Comments: Amazingly lot of things can be done with sprintf() - I could solve nearly all the problems with it - but that would not really be rubyish, , so I have decided for built-in (and one homegrown) functions. , However, , mastering (s)printf() is a very handy thing, , since nearly all big players (C (of course :-)), , C++, , Java, , PHP, , … , ) have it so you get a powerful function in more languages for the price of learning one). , As you can see, , r/ljust is a nice one, , too.

, 8. , Problem: “Open a text file and convert it into HTML file. , (File operations/Strings)”

, Solution: Well, , this problem was not specified in a great detail, , to say the least - or to put it otherwise, , the solvers are given a great freedom to provide a solution spiced up with their fantasy. , This is what I came up with:

,

FINAL_DOC rules = {'*something*' => 'something', , '/something/' => 'something'} rules.each do |k, ,v| re = Regexp.escape(k).sub(/something/) {"(.+?)"} doc.gsub!(Regexp.new(re)) do content = $1 v.sub(/something/) { content } end end doc.gsub!("\n\n") {"\n

, "} final_doc.sub!(/embed_doc_here/) {doc} puts final_doc

  1. doc = <<DOC
  2.  This is the first line in the first paragraph. <b></b>, Nothing really interesting here, , just plain text.
  3.  
  4. This is the second paragraph. <b></b>, Let’s see some *strong* markup in action, , and also /italic/. <b></b>, So far soo good.
  5.  
  6. This is the last paragraph, , with one more <strong>strong tag</strong>.
  7. DOC
  8.  
  9. final_doc = <<FINAL_DOC
  10. <html>
  11.   <head>
  12.     <title>Text to HTML fun!</title>
  13.   </head>
  14.   <body>
  15.     <p>,
  16.     embed_doc_here
  17.     </p>
  18.   </body>
  19. </html>
  20. FINAL_DOC
  21.  
  22. rules = {‘*something*’ => ‘<strong>something</strong>’, ,
  23.          ’/something/’ => ‘<i>something</i>’}
  24.  
  25. rules.each do |k, ,v|
  26.   re = Regexp.escape(k).sub(/something/) {"(.+?)"}
  27.   doc.gsub!(Regexp.new(re)) do
  28.     content = $1
  29.     v.sub(/something/) { content }
  30.   end
  31. end
  32.  
  33. doc.gsub!("\n\n") {"</p>\n<p>, "}
  34.  
  35. final_doc.sub!(/embed_doc_here/) {doc}
  36.  
  37. puts final_doc

, Comments: As you can see, , besides that the text is wrapped around with a minimal HTML, , every occurrence of words between asterisks is outputted in strong and between slashes in italic. , You can add as many such rules as you like, , they will be (hopefully) substituted in the final output.

, 9. , Problem: “Time and Date : Get system time and convert it in different formats ‘DD-MON-YYYY’, , ‘mm-dd-yyyy’, , ‘dd/mm/yy’ etc.”

, Solution: Well, , it was not really clear (for me) what should be the difference between ‘yyyy’ and ‘YYYY’ (resp. , ‘dd’ vs ‘DD’) so again I had to use my imagination. , However, , I guess it does not matter too much, , the solution has to be changed by 1-2 characters only if the original author had something different on his mind.

,

  1. require ‘date’
  2.  
  3. time = Time.now
  4. #’DD-MON-YYYY’, , e.g. <b></b>, 12-Nov-2006 in my interpetation
  5. puts time.strftime("%d-%b-%Y")
  6.  
  7. #’mm-dd-yyyy’, , e.g. <b></b>, 11-12-2006 in my interpetation
  8. puts time.strftime("%m-%d-%Y")
  9.  
  10. #’dd/mm/yy’, , e.g. <b></b>, 12/11/2006 in my interpetation
  11. puts time.strftime("%d/%m/%Y")

, 10. , Problem: “Create files with date and time stamp appended to the name”

, Solution:

,

  1. #Create files with date and time stamp appended to the name
  2. require ‘date’
  3.  
  4. def file_with_timestamp(name)
  5.   t = Time.now
  6.   open("#{name}-#{t.strftime(’%m.%d’)}-#{t.strftime(’%H.%M’)}", , ‘w’)
  7. end
  8.  
  9. my_file = file_with_timestamp(test.txt)
  10. my_file.write(‘This is a test!’)
  11. my_file.close

, Comments: Maybe a more elegant solution could be to subclass File and override its constructor - but maybe that would be an overkill. , I have voted for the latter option in this case :-).

, 11. , Problem: “Input is HTML table. , Remove all tags and put data in a comma/tab separated file.”

, Solution: Since web extraction is both my PhD topic and my everyday job (and even my free-time activity :-)) I will present 3 solutions for this problem. , First, , the classic old-school regexp way (by Paul Lutus), , then with HPricot and finally with scRUBYt!, , a simple yet powerful Ruby web extraction framework currently developed by me.

,

  1. table = <<DOC
  2. <table>
  3.   <tr>
  4.     <td>1</td>
  5.     <td>2</td>
  6.   </tr>
  7.   <tr>
  8.     <td>3</td>
  9.     <td>4</td>
  10.     <td>5</td>
  11.   </tr>
  12.   <tr>
  13.     <td>6</td>
  14.   </tr>
  15. </table>
  16. DOC
  17.  
  18. rows = table.scan(%r{<tr>.*?</tr>}m)
  19.  
  20. rows.each do |row|
  21.    fields = row.scan(%r{<td>(.*?)</td>}m)
  22.    puts fields.join(", ,")
  23. end

, Now for the HPricot solution (in the further examples let’s consider that table is initialized as in the previous example):

  1. require ‘rubygems’
  2. require ‘hpricot’
  3.  
  4. h_table = Hpricot(table)
  5.  
  6. rows = h_table/"//tr"
  7. rows.each do |row|
  8.   child_text = (row/"//td").collect {|elem| elem.innerHTML }
  9.   puts child_text.join(‘, ,’)
  10. end

, and last, , but not least scRUBYt!

  1. require ’scrubyt’
  2.  
  3. table_data = P.table do
  4.                P.cell1
  5.              end
  6.  
  7. table_data.generalize :cell
  8.  
  9. puts table_data.to_csv

, Some explanation: first of all, , at the moment scRUBYt! is avaliable on my hard disk (and partially in my head) only - it should be released around XMAS 2006. , I am using this solution for a little bit of self-promotion :-). ,

, The example works like this: extract something (in this case a HTML <table>) which has something (in this case <td>) which has ‘1′ as its text (well in reality much more is going on in the background, , but roughly along these lines). , This little code snippet will extract the first <td>s of ALL <tables> on a HTML page. , With the ‘generalize’ call we tell the extractor that it should not extract just the first <td> in a table (which is the default setting), , but all of them.

, scRUBYt! can handle much, , much, , MUCH more complicated examples than this (like an ebay or amazon page) and has loads of sophisticated functions… , so stay tuned!

, 12. , Problem: “Extract uppercase words from a file, , extract unique words.”

, Solution: (you can find some_uppercase_words.txt here and some_repeating_words.txt here

,

  1. open(’some_uppercase_words.txt).read.split().each { |word| puts word if word =~ /^[A-Z]+$/ }
  2.  
  3. words = open(’some_repeating_words.txt).read.split()
  4. histogram = words.inject(Hash.new(0)) { |hash, , x| hash[x] += 1; hash}
  5. histogram.each { |k, ,v| puts k if v == 1 }

, 13. , Problem: “Implement word wrapping feature (Observe how word wrap works in windows ‘notepad’).”

, Solution: Unfortunately I am not a Windows user and I have seen notepad a *quite* long time ago - so I am not sure the task and it’s implementation are fully in-line - I have tried my best. , Here we go:

,

  1. input = "Lorem ipsum dolor sit amet, , consectetur adipisicing elit, , sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <b></b>, Ut enim ad minim veniam, , quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. <b></b>, Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. <b></b>, Excepteur sint occaecat cupidatat non proident, , sunt in culpa qui officia deserunt mollit anim id est laborum."
  2.  
  3. def wrap(s, , len)
  4.   result = ”
  5.   line_length = 0
  6.   s.split.each do |word|
  7.     if line_length + word.length + 1  < len
  8.       line_length += word.length + 1
  9.       result += (word + ‘ ‘)
  10.     else
  11.       result += "\n"
  12.       line_length = 0
  13.     end
  14.   end
  15.   result
  16. end
  17.  
  18. puts wrap(input, , 30)

, 14. , Problem: “Adding/removing items in the beginning, , middle and end of the array.”

, Solution:

,

  1. x = [1, ,3]
  2.  
  3. #adding to beginning
  4. x.unshift(0)
  5.  
  6. #adding to the end
  7. x << 4
  8.  
  9. #adding to the middle
  10. x.insert(2, ,2)
  11.  
  12. #removing from the beginning
  13. x.shift
  14.  
  15. #removing from the end
  16. x.pop
  17.  
  18. #removing from the middle
  19. x.delete(2)
  20.  
  21. #we have arrived at the original array!

, 15. , Problem: “Are these features supported by your language: Operator overloading, , virtual functions, , references, , pointers etc.”

, Solution: Well this is not a real problem (not in Ruby, , at least). , Ruby is a very high level language ant these things are a must :).

Finally, , you can download all the solutions in a single archive from here. I would like to see the implementation of these tasks in both Ruby (different (more optimal) solutions of course) as well as in anything else. , If you set out to do something like that, , be sure to drop me a note.

Internet contains huge number of opportunities to earn money online. , Simply create a site that you think has the potential to sell hot items using ruby on rails. , Register a relevant domain name and purchase a web hosting service through hostgator, , one of the better web host out there today. , Get a internet connection through one of the wireless internet providers to upload your site. , Work on search engine optimization to get a better traffic and also use affiliate marketing program for the same reason. , Finally get a free voip phone service to contact customers directly. , The pc to phone system is the most effective method of marketing.


Similar Posts:prozac



If you liked the article, subscribe to the feed   and follow me on twitter!.


      

This entry was posted on Thursday, November 16th, 2006 at 4:31 am and is filed under Devel, Ruby, Tutorial. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

31 Responses to “”

  1. Jamie Macey Says:

    , The “break calculation at a keypress” is as follows - essentially just do a nonblocking read and rescue the “resource not available” exceptions as they come. Just hit enter to kill the loop.

    , i=0
    loop do
    begin
    break if STDIN.read_nonblock(1000)
    rescue Errno::EAGAIN
    end
    puts i
    i += 1
    end

    , For #4, , I’d recommend using @instance variables. Use instancevariableset instead of eval. Eval is very dangerous, , especially when you’re not checking it like there. Storing it in a hash like you have for #5 is good as well.

    , For #8, , the redcloth and bluecloth (textile and markdown, , respectively) are dead-simple html converters.

  2. Satish Talim Says:

    , I liked this post of yours and have requested the readers of my Learning Ruby site to contribute their thoughts etc. to this post.
    http://sitekreator.com/satishtalim/ruby_certification.html

  3. peter Says:

    , Jamie:

    , Thanks for the reply!
    I have modified your code a bit:

    require 'io/nonblock'
    
    i=0
    loop do
      begin
        break if STDIN.nonblock{ STDIN.sysread(100) }
      rescue Errno::EAGAIN
      end
      puts i += 1
    end
    

    , Which is cool - but there is one problem: You need Henry Ford again :-). The original task was to stop on a specified key, , say ‘ESC’ or ‘x’ (and no enter afterwards) and this code stops solely on enter. Can it be modified to stop on ‘esc’?

    , As for the eval - tanks for the suggestion. For #4, , I wanted to write the shortest code possible for better understanding. While #5 is more secure and this is how it should like in a real-life app, , I think it is also harder to comprehend for a beginner. But anyway, , the moral of the story is that we should not use eval too much :-)

    , RedCloth/BlueCloth - I will check them out and ad them to the solution.

  4. peter Says:

    , Satish:

    , Cool! I hope a conversation, , beneficial for both parties, , will be started :-). There are tons of other ways to code these examples and I would like to hear other ideas as well. Thanks.

  5. Subbu Says:

    , Hey i had no clue about Ruby until this morning.But think i am falling in love with it..your codes were really helpful for me to have a look at how basic ruby programming will be…
    a single glitch :
    the link in the problem No:6 to download the code for it is not proper.It redirects to the same page.

  6. peter Says:

    , Subbu, ,

    , Thanks for the ‘bug report’. It should be corrected by now.

  7. Ruby, Rails, Web2.0 » Blog Archive » Site Updates Says:

    , [...] « Implementing ‘15 Exercises for Learning a new Programming Language’ [...]

  8. Ken Laninga Says:

    , Hello, , (?????) I don’t think I saw your name………. sorry if I’m blind…….

    , Just heard about Ruby yesterday and it looks fascinating. I programmed a lot in QuickBasic loooooong ago but Win95 put me out of that business.

    , Everybody shows bits of Ruby code, , but nobody starts far enough back to tell me HOW to do that; do I just type the code in Notepad or Wordpad and then save it as abcd.exe and run it? (or compile it into .exe first)

    , Can we start at “square one” please? Some of us are n00bs.

  9. peter Says:

    , Hi Ken, ,

    , My name is Peter (if you go to https://rubyrailways.com, , there is a ‘whoami’ link on the right)… It’s kinda linux-style so it may look weird to some non-*nix guys :-)

    , QuickBasic was cool… I also used to program a lot in it (after I got my first PC - before that I had a Sinclair ZX Spectrum and a Commodore 64, , so those were my first BASICs :-) but ruby is much, , much cooler…

    , As for the HOWTO part: Ruby is (like BASIC) an intepreted language - this means that the code is not compiled to a binary format (though it is posible to do so) but interpreted on the fly. So you enter the stuff into notepad, , then save the file as ‘mycoolprogram.rb’ and either type

    ruby my_cool_program.rb
    

    , to a commadline shell, , or set up a file association on the type ‘.rb’ and just double click it (however, , some further tweaking may be needed here , , since if I remember correctly a shell pops up with the output then it closes immediately so you can not inspect the output).

    , First you should install Ruby: Check out this page: http://rubyinstaller.rubyforge.org/

    , Then you should make sure that ruby is in the path… and this should be about it.

    , If you still have questions, , don’t hesitate to write me (at peter@[name of this site].com). The Ruby mailing list is also a good place to start, , no matter how noob or expert you are - the people are really helpful.

    , Hope this helps…

  10. Robert Says:

    , Great read. It shows a lot of the ways that Ruby establishes itself from the other languages. My only real comment is that on problem 5. The question says “if you say ‘y’, , it’ll again ask the parameters. If ‘n’, , it’ll exit”. The way you have it implemented is so that anything other than ‘n’ will continue the loop. It wouldn’t be a bad idea to throw in a method that check for y/n and if gets is !y/n then shout out some type of “Invalid char.” nonsense and have it re-loop the y/n question. This isn’t really an issue with the programming, , just a statement to those confused by why when they accidentally hit ‘/[^n]/’ on their keyboard. All in all, , I think it is great that you put this up. Now, , if others would just make more like yours but in different languages.

  11. botp Says:

    , Hi Peter, ,

    , very nice blog.
    as for problem #1, , you can do something like the ff (in windows), ,

    , C:\family\ruby\key_press>cat a1b.rb


    , require ‘Win32API’

    , @@kbhit = Win32API.new(”msvcrt”, , “kbhit”, , [], , ‘I’)
    @@getch = Win32API.new(”msvcrt”, , “
    getch”, , [], , ‘I’)

    , def exit_onkey key
    unless @@kbhit.call.zero?
    c = @@getch.call
    if c == key
    exit
    end
    end
    end

    , KEY_Esc = 27
    $stdout.sync=true

    , i=0
    loop do
    exitonkey KEYEsc
    puts “#{i+=1}”
    end


    , note, , that we created another method exit_onkey just for readability and flexibility purposes.
    kind regards -botp

  12. Satish Talim Says:

    , Anyone here has used ncurses for problem no. 1?

  13. links for 2007-05-23 « mriror Says:

    , [...] Ruby, , Rails, , Web2.0 » Blog Archive » Implementing ‘15 Exercises for Learning a new Programming Language’ [...]

  14. bshand Says:

    , In lines 11-12 of example 13, , I think you mean:
    result += “\n” + word + ‘ ‘
    linelength = word.length + 1
    instead of
    result += “\n”
    line
    length = 0
    otherwise the words that trigger line breaks are lost.
    Or, , with slightly less repetition:
    s.split.each do |word|
    if linelength + word.length + 1 >= len
    result += “\n”
    line
    length = 0
    end
    line_length += word.length + 1
    result += (word + ‘ ‘)
    end

  15. Jakob Says:

    , This is exactly what I expected to find out after reading the title . Thanks for informative article

  16. links for 2007-08-23 « Bloggitation Says:

    , [...] Implementing 15 Exercises for Learning a new Programming Language’ implement them in your favorite language (tags: ruby programming blog) [...]

  17. Hotels Vlaanderen Says:

    , Great blog !

  18. wurzel Says:

    , I cant get the break on ENTER loop working on ruby 1.8.6

    , require ‘io/nonblock’

    , i=0
    loop do
    begin
    break if STDIN.nonblock{ STDIN.sysread(100) }
    rescue Errno::EAGAIN
    end
    puts i += 1
    end

    , any ideas why?

    , I get this error

    , loopESC.rb:6: undefined method nonblock' for #<IO:0x2846b04> (NoMethodError)
    from loopESC.rb:4:in
    loop’
    from loopESC.rb:4

  19. Figet Says:

    , Nice blog!

  20. knownone Says:

    , are your platform windows?nonblock.rb requires fcntl, ,but it didn’t implement on all platforms?

  21. James Edward Gray II Says:

    , I see there’s already a Windows specific answer to the first problem, , so I shall provide the Unix solution:

    #!/usr/bin/env ruby -wKU
    
    require "io/wait"
    
    state = `stty -g`
    begin
      system "stty raw -echo cbreak isig"
    
      1.upto(1.0/0.0) do |n|
        puts n
        exit if $stdin.ready? and $stdin.getc == 27
      end
    
    ensure
      system "stty #{state}"
    end
    
    __END__
    

    , The reason you need the platform specific code here is that you are doing complex interactions (reading and writing at the same time) with a terminal and all terminals are different.

  22. Vince Says:

    , In solution #3 instead of << p a.sort { |a, ,b| b<=>a } >> you could use << p a.sort.reverse >>…just more readable

  23. Diesel Says:

    ,

  24. Bill Says:

    ,

  25. links for 2008-03-29 | Moewes.com Says:

    , [...] Ruby, , Rails, , Web2.0 » Blog Archive » Implementing ‘15 Exercises for Learning a new Programming Language’ (tags: programming) [...]

  26. Thando Vuzane - Net Age Says:

    , Has anyone here created a helper.rb for a vCard on Rails? Please post an example of your coding if you have.

    , Thanx!

  27. Thando Vuzane - Net Age Says:

    , Wow, , thank you for this post. I will go home and do the ‘15 exercises for learning a new Programming Language’. And I’ll use the above coding as my reference. I’ve just recently started developing in Ruby on Rails, , so I’m at a point where I just want as many challenges and new applications to develop as possible, , because I want to fully explore RoR.

    , Thank you again, ,

  28. Jeff Leitman Says:

    , For a simpler UNIX solution, , you can trap SIGINT (Ctrl-C)

    i = 0
    go = true
    while go do
     print "#{i+=1}, , "
     Signal.trap("INT") do
      go = false
     end
    end
    puts "Terminated by user."
    
  29. John Says:

    , In response to problem 1, , interrupting an infinite sum by hitting a character:

    , Without doing threads in Ruby (like you would in Python, , for ex), , maybe you can do something simple like check for a kbhit (received character from std in) in your loop. This is a common technique when reading rs-232 serial lines on a microcontroller. You want to get data if its in a buffer, , but if it is not then you absolutely can’t hang in a get operation.

    , something like:

    , if(kbhit())
    car=getc()

    , I’m 2 hours into this language, , so I don’t know if this method exists, , but it seems like it probably does.

  30. Amit Verma Says:

    , Good article.

    , Also, , good reply from “Jeff Leitman” for Problem #1.

    , Thanks.

  31. Purui Says:

    , In #13, , first word since 2nd line will skipped. Looks like a bug.

Leave a Reply




Bad Behavior has blocked 2380 access attempts in the last 7 days.