[Code] Touch Typing Tutor What do you think of my code?

Discussion in 'Ruby' started by Justin brainy, Mar 9, 2011.

  1. Hello! I'm new to Ruby, but I spent some time with C. I would like to
    know if the program I wrote was syntaxically correct for a Ruby program.
    For example, I used a while loop to iterate through a string (with a
    "i") to compare two strings... Should I have used Ruby's iterator?

    Basically, the program is a *very* simple touch typing tutor. It reads
    through a file to set the "lecture, for example : "jfjf fff ff jjf fj
    jjjf fj" and then prints the line and asks the user for his answer. It
    calculates number of errors (n_erreurs in french), precision in %, time
    (okay too?).

    Thanks !

    ------------------------------------------------------------------------

    Code:
    
    #!/usr/bin/ruby
    
    # Fichier de lecture
    f = File.open("lecture.txt" ,"r")
    s_file = f.readline
    f.close
    
    # Variables & Constantes
    n_erreurs = precision = 0
    n_char = s_file.length
    BUT = 95  # %
    L_PAGE = 40
    
    puts "Tapez le texte suivant :"
    puts
    print "Debute dans 3 ."
    sleep 1
    print " 2 ."
    sleep 1
    puts "1"
    sleep 1
    puts
    
    puts s_file
    
    t_1 = Time.now
    s_input = gets.chomp
    t_2 = Time.now
    
    i = 0
    
    puts
    puts "Resultats".center(L_PAGE)
    
    while(i.to_i < n_char)
    # Comparaison des deux chaines
    if (s_file[i] != s_input[i])
    n_erreurs = n_erreurs + 1
    # puts "Erreur : ##{i}"
    end
    
    i = i + 1
    end
    
    precision = (100 - ( n_erreurs.to_f / n_char ) * 100).floor
    
    puts
    puts "Nombre d'erreurs : #{n_erreurs}"
    puts "Nombre de caracteres : #{n_char}"
    puts "Precision : #{precision} %"
    puts "Temps : #{(t_2 - t_1).floor} s"
    puts (precision > BUT) ? "Objectif atteint !" : "Objectif manque"
    puts
    
    
    -------------------------------------------------------------------------

    Attachments:
    http://www.ruby-forum.com/attachment/6015/touchtutor.rb


    --
    Posted via http://www.ruby-forum.com/.
    Justin brainy, Mar 9, 2011
    #1
    1. Advertising

  2. Justin brainy

    JP Billaud Guest

    Hey,

    I think your code looks way too much like C. IMO, if you end up using
    C-like loop statement such as while or for it most likely means you are
    not doing very good Ruby-like coding.

    The way I would do your while loop would be something like this:

    =====

    #!/usr/bin/ruby

    class String
    def compare_sum_errors other
    cnt = [self.length, other.length].min

    (0..(cnt-1)).inject(0) do |errors, idx|
    next errors + 1 if self[idx] != other[idx]
    errors
    end + (self.length - other.length).abs
    end
    end

    str1 = "test origin string"
    str2 = "test diff string"

    puts str1.compare_sum_errors str2

    =====

    Hope it helps,

    --
    Posted via http://www.ruby-forum.com/.
    JP Billaud, Mar 9, 2011
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    On Wed, Mar 9, 2011 at 11:27 PM, JP Billaud <> wrote:

    > class String
    > def compare_sum_errors other
    > cnt = [self.length, other.length].min
    >
    > (0..(cnt-1)).inject(0) do |errors, idx|
    > next errors + 1 if self[idx] != other[idx]
    > errors
    > end + (self.length - other.length).abs
    > end
    > end
    >
    > str1 = "test origin string"
    > str2 = "test diff string"
    >
    > puts str1.compare_sum_errors str2
    >


    This isn't the best use of inject. :)

    This is much more readable, I find:

    def count_errors(first, second)
    # reorder things so that first is always <= second
    first, second = [first, second].sort_by { |s| s.length }

    errors = 0

    first.chars.zip(second.chars).each do |f, s|
    errors += 1 if f != s
    end

    # over-typing is an error
    errors + (second.length - first.length)
    end

    count_errors("hello", "helloo") #=> 0
    count_errors("hello", "helllo") #=> 2

    str1 = "test origin string"
    str2 = "test diff string"
    count_errors(str1, str2) #=> 13 (same result as the inject)
    Adam Prescott, Mar 9, 2011
    #3
  4. Okay, thanks a lot guys!

    I will finish my book and rewrite the program with a more ruby-like
    syntax. The thing is I haven't read a lot about methods and classes
    yet... guess I'll need some time to get used to Ruby too.

    Meanwhile, I will study the code you gave me and figure out your "Ruby
    Way".

    Again, thank you very much and I hope to help you soon :p

    --
    Posted via http://www.ruby-forum.com/.
    Justin Wadsworth, Mar 10, 2011
    #4
  5. > I will finish my book and rewrite the program with a more ruby-like
    > syntax. The thing is I haven't read a lot about methods and classes
    > yet... guess I'll need some time to get used to Ruby too.


    Methods and classes will allow you to avoid repeating the same code over and over. (For example in your original program you do a lot of print-get-sleep.)

    Code that doesn't repeat itself is shorter, easier to test, and easier to understand -- which means that it's easier to fix; much easier.

    Ruby programmers talk a lot about DRY: that just means "Don't Repeat Yourself". The golden target for any ruby programmer is never to code the same bit of code more than once, ever. (Of course it never works out quite that way, but it's a nice goal.)
    Shadowfirebird, Mar 10, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Throw
    Replies:
    4
    Views:
    386
    RedGrittyBrick
    Oct 28, 2005
  2. JimLad
    Replies:
    0
    Views:
    497
    JimLad
    Jan 26, 2010
  3. Han Holl
    Replies:
    4
    Views:
    333
    Nobuyoshi Nakada
    Oct 12, 2006
  4. Throw
    Replies:
    9
    Views:
    92
  5. David Mark
    Replies:
    17
    Views:
    234
    David Mark
    Mar 23, 2010
Loading...

Share This Page