Distrubute students by percent criteria

Georgi

I have criteria which value is percent.

criteria = {"Top" => 20, "Excellent" =>  30, "Average" => 30, "Poor" => 20 

I have student hash. Keys are student id and values are student score

students = { 1 => 80,
             2 => 90,
             3 => 30,
             4 => 50,
             5 => 120,
             6 => 90,
             7 => 50,
             8 => 50,
             9 => 50,
             10 => 30}

Crietria is added by teachers. Student places are calculated this way, because i cant get for example 2.5 students:

students_positions = criteria.map {|k, v| (students.count * (v.to_f/100)).ceil }
f=> [2, 3, 3, 2]

First thing i do is sorting students by their value(score)

sorted_students = students.sort {|a1,a2| a2.last <=> a1.last }.to_h
=> {5=>120, 2=>90, 6=>90, 1=>80, 8=>50, 4=>50, 7=>50, 9=>50, 3=>30, 10=>30}

The result should be 20%(2 student positions) of students from student hash get 'Top' criteria, 30%(3 student positions) get 'Excellent' and etc. If two students have same score but are placed in different criteria group should both be in previous critera group. For example One is in Top with score 90 and other is in Execellent with score 90, second one must be moved to Top crietria group.

How can i split students by criteria

Best regards, Georgi

sawa

Modifying the given expressions (the first of which is not a Ruby expression) to Ruby expressions:

criteria = {"Top" => 20, "Excellent" =>  30, "Average" => 30, "Poor" => 20}
students = {
  1 => 80,
  2 => 90,
  3 => 30,
  4 => 50,
  5 => 120,
  6 => 90,
  7 => 50,
  8 => 50,
  9 => 50,
  10 => 30
}

Converting the values to something useful:

n = 0
accumulated_counts =
criteria
.each_with_object({}){|(k, v), h| h[k] = n += students.length * v / 100.0}

# =>
# {
#   "Top"       => 2.0,
#   "Excellent" => 5.0,
#   "Average"   => 8.0,
#   "Poor"      => 10.0
# }

students_by_score =
students.group_by(&:last).sort.reverse.map{|a| a.last.map(&:first)}

# => [[5], [2, 6], [1], [4, 7, 8, 9], [3, 10]]

Distributing the students:

n = 0
accumulated_counts
.each_with_object(Hash.new{|h, k| h[k] = []}) do |(k, v), h|
  h[k].push(*students_by_score.shift) while n + h[k].length < v
  n += h[k].length
end

# =>
# {
#   "Top"       => [5, 2, 6],
#   "Excellent" => [1, 4, 7, 8, 9],
#   "Average"   => [],
#   "Poor"      => [3, 10]
# }

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related