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
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.
Comments