Otra manera de calcular la media ponderada en Ruby

Esto que escribo es un poco chorra, lo sé, pero llevo tanto tiempo sin escribir que me parece que puede ser gracioso poner esto aquí.
Hoy me he enfrentado al “terrible y dificil” reto de calcular una media ponderada de datos, más concretamente las notas de los alumnos en una asignatura.
Partimos de tener un hash en el que se define, para cada nota, los alumnos que la han obtenido. Por ejemplo (No han sacado muy buenas notas, la verdad):

{4.0=>7, 3.0=>3, 6.0=>3, 9.0=>1, 7.0=>5, 10.0=>1, 5.0=>2, 2.0=>2, 8.0=>1}

Según la definición del calculo, deberíamos acumular, por un lado, la nota multiplicada por el número de alumnos que la han obtenido y por otro el número de alumnos totales que han cursado la asignatura.
Una manera estándar de hacer esto seria:

total_peso = hash.inject(0){|result, e| result += e[0]*e[1]}
total_alumnos = hash.inject(0){|result, e| result += e[1]}
media = total_peso/total_alumnos

Hay que reconocer que ruby tiene cosas muy interesantes y que, usadas con imaginación, pueden ayudarnos a mejorar mucho el código. Y una de ellas, que es la que comento aqui, es la posibilidad de multiplicar un array por un valor. Si a cada elemento del hash multiplicamos la nota convertida en array por el número de alumnos que han obtenido esa nota obtendremos un array con todas las notas de todos los alumnos. A partir de ahí basta aplicar el método avg del Array para que Ruby calcule la media. Esto es lo mismo que antes, pero reduciendo enormemente el código:

hash.map{|k,v| [k] * v}.flatten.avg

Todavía no hay comentarios

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.
  • Etiquetas HTML permitidas: <a> <blockquote> <br> <cite> <code> <dd> <div> <dl> <dt> <em> <h1> <h2> <h3> <h4> <h5> <h6> <hr> <img> <li> <ol> <p> <pre> <span> <strong> <swf> <table> <tbody> <td> <th> <tr> <ul>
    Allowed Style properties: background-color, background-image, border, border-bottom, border-bottom-color, border-bottom-style, border-bottom-width, border-color, border-left, border-left-color, border-left-style, border-left-width, border-right, border-right-color, border-right-style, border-right-width, border-spacing, border-style, border-top, border-top-color, border-top-style, border-top-width, border-width, color, direction, font, font-family, font-size, font-style, font-variant, font-weight, height, left, line-height, list-style-type, margin, margin-bottom, margin-left, margin-right, margin-top, padding, padding-bottom, padding-left, padding-right, padding-top, right, text-align, text-decoration, top, width
  • Syntax highlight code surrounded by the {syntaxhighlighter OPTIONS}...{/syntaxhighlighter} tags.
  • E-Mail addresses are hidden with reCAPTCHA Mailhide.

Más información sobre opciones de formato

CAPTCHA
Esta pregunta es para comprobar si eres un ser humano y evitar el envío automático desde sistemas de spam