Update
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Dominic Grimm 2022-12-17 12:27:31 +01:00
parent 44d6f59453
commit 8c10ecf184
No known key found for this signature in database
GPG key ID: 6F294212DEAAC530
5 changed files with 92 additions and 10 deletions

View file

@ -181,3 +181,4 @@ trigger:
- main
event:
- push
- promote

View file

@ -23,7 +23,7 @@ POSTGRES_PASSWORD=
# Backend
BACKEND_MINIMUM_TEACHER_SELECTION_COUNT=6
BACKEND_ASSIGNMENT_POSSIBILITY_COUNT=500
BACKEND_ASSIGNMENT_POSSIBILITY_COUNT=65536
BACKEND_URL=URL
# Backend - API
BACKEND_API_JWT_SECRET=

View file

@ -17,7 +17,6 @@
require "ldap"
require "uuid"
require "uuid/json"
require "random/secure"
module Backend
module Api

View file

@ -88,11 +88,8 @@ module Backend
end
user = Db::User.create!(username: username, role: role.to_s, admin: opts.bool["admin"])
case role.to_api
in Api::Schema::UserRole::Student
if role == Db::UserRole::Student
Db::Student.create!(user_id: user.id)
in Api::Schema::UserRole::Teacher
# Db::Teacher.create!(user_id: user.id)
end
Worker::Jobs::CacheLdapUserJob.new(user.id).enqueue

View file

@ -54,11 +54,96 @@ module Backend
teachers = Db::Teacher.query
.where do
raw("EXISTS (SELECT 1 FROM teacher_votes WHERE teacher_id = teachers.id)") &
max_students > 0
(max_students > 0)
end
pp! teachers
students = Db::Student.query.with_vote(&.with_teacher_votes).to_a
pp! students
.with_teacher_votes
.to_a
vote_index = Hash.zip(teachers.map(&.id), [0] * teachers.size)
teacher_votes : Hash(Int32, Array(TeacherVote)) = Hash.zip(
teachers.map(&.id),
teachers.map do |t|
t.teacher_votes.map do |tv|
vote_index[t.id] += 1
{
student: tv.vote.student.id,
priority: tv.priority,
}
end
end
)
teachers.sort_by! { |t| vote_index[t.id] }
students = Db::Student.query
.with_vote(&.with_teacher_votes(&.order_by(priority: :desc)))
.to_a
students.each do |s|
p! s
pp! s.vote.not_nil!.teacher_votes
end
student_ids = students.map(&.id)
votes = Hash.zip(
student_ids,
students.map do |s|
s.vote.not_nil!.teacher_votes
.to_a
.select { |tv| teacher_votes.has_key?(tv.teacher.id) }
.map do |tv|
{
teacher: tv.teacher.id,
teacher_max_students: tv.teacher.max_students,
}
end
end
)
votes_a = votes.to_a
best : {assignment: Hash(Int32, Assignment), score: UInt32}? = nil
Backend.config.assignment_possibility_count.times.each do
assignment = {} of Int32 => Assignment
assignment_count = Hash.zip(teachers.map(&.id), [0] * teachers.size)
votes_a.shuffle(Random::Secure).each do |s, tvs|
tvs.each_with_index do |tv, i|
if assignment[s]?.nil?
assignment_count[tv[:teacher]] += 1
assignment[s] = {teacher: tv[:teacher], priority: i}
elsif assignment_count[tv[:teacher]] < tv[:teacher_max_students]
assignment_count[assignment[s][:teacher]] -= 1
assignment_count[tv[:teacher]] += 1
assignment[s] = {teacher: tv[:teacher], priority: i}
end
end
end
score = 0_u32
assignment.each do |s, a|
score += a[:priority] ** 2
end
if best.nil?
best = {
assignment: assignment,
score: score,
}
elsif score < best.not_nil![:score]
best = {
assignment: assignment,
score: score,
}
end
end
pp! best
str = String.build do |str|
str << "===========================\n"
best.not_nil![:assignment].each do |s, a|
pp! a
str << "#{Db::Student.query.find!(s).user.username} #{s} : #{Db::Teacher.query.find!(a[:teacher]).user.username} #{a[:priority]} (#{votes[s].size - a[:priority]} / #{votes[s].size})\n"
end
str << "===========================\n"
end
print str
end
end
end