Method to return elements of an array in numeric 'rank'?

Jenny Purcell wrote:

I would expect there would be an existing method that works off of the
array class that would do this, and I'd like to check on that before
(painfully) writing my own nested loops that would do the same thing.

See module Enumerable - RDoc Documentation

Look at sort_by

Also, in your code, consider representing objects of interest (such as horses and races) by defining suitable classes.

I think you code would be easier to follow if, for example, it managed a collection of Horse objects.

···

--
James Britt

http://web2.0validator.com - We're the Dot in Web 2.0
http://www.rubyaz.org - Hacking in the Desert
http://www.jamesbritt.com - Playing with Better Toys

Would something like this work?

arr = [[1,7],[3,2],[4,9],[2,3]] # [[horse,score],[horse,score] etc.]
arr.sort! {|x,y| y[1] <=> x[1]}
p arr

Harry

···

On 7/22/07, Jenny Purcell <dontspamme@spam.com> wrote:

I realize it would be easier for people in the fgroup to follow if I
was programming with objects. However, I just don't understand OO
programming, my skills (such as they are) are procedural.

Ruby was pointed out to me as a language that would allow me to write
procedural programs and so far it is working out very nicely in that
regard.

--
A Look into Japanese Ruby List in English

Jenny Purcell wrote:

Jenny Purcell wrote:

I would expect there would be an existing method that works off of the
array class that would do this, and I'd like to check on that before
(painfully) writing my own nested loops that would do the same thing.

See module Enumerable - RDoc Documentation

Look at sort_by

Also, in your code, consider representing objects of interest (such as horses and races) by defining suitable classes.

I think you code would be easier to follow if, for example, it managed a collection of Horse objects.

I realize it would be easier for people in the fgroup to follow if I
was programming with objects. However, I just don't understand OO
programming, my skills (such as they are) are procedural.

Skill to do comes of doing. And you can ask for help on ruby-talk.

Ruby was pointed out to me as a language that would allow me to write
procedural programs and so far it is working out very nicely in that
regard.

That will not carry very far.

While it is technically true that one can use Ruby to write procedural code that does not make it a good idea.

It's a fair bet that at some point maintainability will approach zero unless you employ some higher abstractions Classes and objects are one approach to this.

When you have procedural code that works (and you *are* using Ruby's unit testing libraries, right? :)) consider refactoring it into something more OO. It might make life simpler all around.

Just a suggestion.

···

On Sun, 22 Jul 2007 11:44:40 +0900, James Britt > <james.britt@gmail.com> wrote:

--
James Britt

"In physics the truth is rarely perfectly clear, and that is certainly
  universally the case in human affairs. Hence, what is not surrounded by
  uncertainty cannot be the truth."
  - R. Feynman

Ruby is an excellent place to get started with OO as it requires *much* less repetitious coding than, say, Java.

I've taken the liberty of changing your code slightly to use a Horse class and keep your horses in a collection 'horses'. I've tried to stay as true to the original code as possible, just changing what's required.
Basically, I've removed all the arrays into a Horse class which we can use to create new horses by calling its 'new' method with the line from the csv file (Horse.new calls Horse::initialize. I have not idea why the different names, just something to be aware know)

Cheers,
Dave

#! /usr/bin/env ruby

require 'csv'

# Written by Jenny Purcell based off starter code
# provided by Robbert Haarman

class Horse
   attr_reader :horse_name, :horse_info, :owners_initials, :best_result,
     :race_style, :best_time, :pre_points, :rolls, :score
   attr_accessor :new_pole

   def initialize(record)
     # Now we assign the appropriate fields of the record to
     # variables named after the fields in the CSV file.
     # Note that we need to call .to_i on the 6th field
     # to convert it from strings to integers.
     @horse_name = record[0]
     @horse_info = record[1]
     @owners_initials = record[2]
     @best_result = record[3]
     @race_style = record[4]
     @best_time = record[5]
     @pre_points = record[6].to_i

     # Roll the dice.
     # This generates an array containing five die rolls,
     # each die roll ranging from 1 to 6
     @rolls= (1..5).map { rand(6) + 1 }

     # Calculate score.
     # The score is the sum pre_points, and each of the die rolls
     @score= @rolls.inject(pre_points){|sum, i| sum+ i}
   end # initialize
end # Horse

# create an array to keep all our horses in
horses=

# For each record in the CSV file...
CSV::Reader.parse(File.open('horses.csv')) do |record|
   horses << Horse.new(record)
end # record

# Randomizing Post Position
Array.new(horses.size){ |m| m + 1 }.sort_by{ rand }.each_with_index do |pole, index|
   horses[index].new_pole= pole
end # pole, index

horses.each do |horse|
   puts CSV.generate_line([
     horse.pole_new,
     horse.horse_name,
     horse.horse_info,
     horse.owners_initials,
     horse.best_result,
     horse.race_style,
     horse.best_time,
     horse.pre_points]+
     horse.rolls+
     [horse.score])
     i = i + 1
end # horse

     # Features to add
     # Break ties.
     # Have it calculate race times
     # Have it calculate margins
     # Have it share out pre_points based on running style (adapt to
     # numbered "legs")
     # Have it export to basic HTML file (for archive/email results)
     # all sixes = possible NTR?
     # Two consecutive ones is a break in pace.

···

On 22/07/2007, at 1:59 PM, Jenny Purcell wrote:

However, I just don't understand OO
programming, my skills (such as they are) are procedural.

What I'm thinking is that you could set up a 2D array and sort it on
the scores (element [1] of each sub-array).
Then you can extract the data you want.
You can do it using only arrays, which I think you said you wanted to do.
This is not a total solution, just an idea.

arr = [[1,7],[3,2],[4,9],[2,3]] # [horse,score],[horse,score] etc.]
arr.sort! {|x,y| y[1] <=> x[1]}
p arr #> [[4,9],[1,7],[2,3],[3,2]]
puts
p arr[0] #>[4,9]
p arr[1] #>[1,7]
p arr[2] #>[2,3]
puts
p arr[0][0] #> 4
p arr[0][1] #> 9
p arr[1][0] #> 1
p arr[1][1] #> 7

Harry

···

On 7/22/07, Jenny Purcell <dontspamme@spam.com> wrote:

It looks like you're suggesting a two dimensional array, is that
correct? I think that would also work, although I'm not quite good
enough with Ruby syntax (or arrays) to follow it 100%.

Jenny

--
A Look into Japanese Ruby List in English