Archivos csv y Ruby

Standard

Hola espero y estén bien, aquí estamos otra vez en un nuevo post, espero y sea de ayuda.

El día de hoy hablaremos un poco de como poder leer archivos csv con ruby. Esta tarea es muy simple pero también muy útil, es por eso que la abordamos, así que vamos a empezar. Para el ejemplo sobre el cual trabajaremos nos enfocaremos en algo muy sencillo como calcular el promedio de estudiantes, para nuestro propósito definiremos una clase Student .

1
2
3
4
5
6
7
8
9
10
11
class Student
    attr_accessor :name
    attr_accessor :calif
      def initialize(name,calif)
        @name=name
        @calif=calif
      end
      def to_s
          puts "#{@calif}"
      end
end

Por consiguiente tendremos que definir una clase para leer el archivo csv llamada LeeCsv la cual tendrá la siguiente estructura:

1
2
3
4
5
6
7
8
9
10
11
class LeeCsv
    def initialize
    # ..
    end
    def read_in_csv_data(csv_file_name)
    # ...
    end
    def average
    # ...
    end
end

Empezaremos por definir una variable de instancia dentro de la función initialize, donde acumularemos los valores del archivo:

1
2
3
def initialize
  @persons = []
end

Ahora y lo más interesante es leer el archivo csv y eso lo realizaremos dentro de la función read_in_csv_data, la cual lucirá así:

1
2
3
4
5
def read_in_csv_data(csv_file_name)
      CSV.foreach(csv_file_name, headers: true) do |row|
        @students << Student.new(row["NAME"], row["CALIF"])
        end
end

Cabe recalcar que el archivo csv llevará esta estructura:

1
2
3
4
5
"NAME","CALIF","CITY"
"Jose",100,"Sinaloa"
"Jesus",80,"Chihuahua"
"Mario",87,"Sonora"
etc etc etc

En la primer linea establecemos a la biblioteca que abra el archivo csv, headers: true indica que deseamos parsear la primer linea como los nombres de las columnas, se recorre el archivo completo y a su vez se almacenan en la variable students creando una nueva instancia por cada estudiante que se incluirá en el array.

Ahora para ilustrar en la función average obtendremos el promedio de las calificaciones que obtendremos del archivo csv.

1
2
3
4
5
6
7
8
9
def average
      sum = 0.0
      @students.each {|p|
          sum += p.calif.to_f
          puts "#{p.calif}"
      }
      sum = (sum/@students.length).to_f
      sum.round(2)
end

Aquí recorremos el array y sacamos el promedio de todas las calificaciones de los estudiantes y lo redondeamos a un valor con 2 cifras de precisión.

Casi terminamos, la estructura de los archivos quedara de la siguiente manera:

1
2
3
4
5
6
7
8
9
10
11
12
13
#student.rb

class Student
    attr_accessor :name
    attr_accessor :calif
      def initialize(name,calif)
        @name=name
        @calif=calif
      end
      def to_s
          puts "#{@calif}"
      end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#LeeCsv.rb

require 'csv'
require_relative 'student'
class LeeCsv
    def initialize
        @students = []
    end
    def read_in_csv_data(csv_file_name)
      CSV.foreach(csv_file_name, headers: true) do |row|
        @students << Student.new(row["NAME"], row["CALIF"])
        end
    end    
    def average
      sum = 0.0
      @students.each {|p|
          sum += p.calif.to_f
          puts "#{p.calif}"
      }
      sum = (sum/@students.length).to_f
      sum.round(2)
    end   
end

Ahora tendremos un archivo con el nombre main.rb con lo siguiente para ejecutarlo:

1
2
3
4
5
6
7
8
#main.rb
require_relative 'LeeCsv'
obj=LeeCsv.new
ARGV.each do |csv_file_name|
  STDERR.puts "Processing #{csv_file_name}"
  obj.read_in_csv_data(csv_file_name)
end
puts "Average = #{obj.average}"

Y eso es todo si ejecutamos nuestro archivo main tendremos el promedio de los estudiantes:

run

Bueno hasta aquí llegamos con este minipost, espero y les sirva.

 

Leave a Reply

Your email address will not be published. Required fields are marked *