Update discomfort calculator to use group ids
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 52s
Run unit tests / unit_tests (pull_request) Successful in 1m23s
Build Nginx-based docker image / build-static-assets (pull_request) Successful in 16m27s

This commit is contained in:
Manuel Bustillo 2024-11-01 12:04:15 +01:00
parent b5693f549e
commit d37dd44cd3
3 changed files with 48 additions and 43 deletions

View File

@ -14,23 +14,23 @@ class AffinityGroupsHierarchy < Array
end end
end end
def find(name) def find(id)
@references[name] @references[id]
end end
def <<(name) def <<(id)
new_node = Tree::TreeNode.new(name) new_node = Tree::TreeNode.new(id)
super(new_node).tap { @references[name] = new_node } super(new_node).tap { @references[id] = new_node }
end end
def register_child(parent_name, child_name) def register_child(parent_id, child_id)
@references[parent_name] << Tree::TreeNode.new(child_name).tap { |child_node| @references[child_name] = child_node } @references[parent_id] << Tree::TreeNode.new(child_id).tap { |child_node| @references[child_id] = child_node }
end end
def distance(name_a, name_b) def distance(id_a, id_b)
return nil if @references[name_a].nil? || @references[name_b].nil? return nil if @references[id_a].nil? || @references[id_b].nil?
@references[name_a].distance_to_common_ancestor(@references[name_b]) @references[id_a].distance_to_common_ancestor(@references[id_b])
end end
private private

View File

@ -14,7 +14,7 @@ module Tables
private private
def cohesion_penalty def cohesion_penalty
table.map { |guest| guest.affinity_group_list.first }.tally.to_a.combination(2).sum do |(a, count_a), (b, count_b)| table.map(&:group_id).tally.to_a.combination(2).sum do |(a, count_a), (b, count_b)|
distance = AffinityGroupsHierarchy.instance.distance(a, b) distance = AffinityGroupsHierarchy.instance.distance(a, b)
next count_a * count_b if distance.nil? next count_a * count_b if distance.nil?

View File

@ -5,6 +5,11 @@ module Tables
RSpec.describe DiscomfortCalculator do RSpec.describe DiscomfortCalculator do
let(:calculator) { described_class.new(table) } let(:calculator) { described_class.new(table) }
let(:family) { create(:group, name: 'family') }
let(:friends) { create(:group, name: 'friends') }
let(:work) { create(:group, name: 'work') }
let(:school) { create(:group, name: 'school') }
describe '#cohesion_penalty' do describe '#cohesion_penalty' do
before do before do
# Overridden in each test except trivial cases # Overridden in each test except trivial cases
@ -14,16 +19,16 @@ module Tables
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(group, group).and_return(0) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(group, group).and_return(0)
end end
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('family', 'friends').and_return(nil) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(family.id, friends.id).and_return(nil)
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('friends', 'work').and_return(1) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(friends.id, work.id).and_return(1)
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('family', 'work').and_return(2) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(family.id, work.id).and_return(2)
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('family', 'school').and_return(3) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(family.id, school.id).and_return(3)
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('friends', 'school').and_return(4) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(friends.id, school.id).and_return(4)
allow(AffinityGroupsHierarchy.instance).to receive(:distance).with('work', 'school').and_return(5) allow(AffinityGroupsHierarchy.instance).to receive(:distance).with(work.id, school.id).and_return(5)
end end
context 'when the table contains just two guests' do context 'when the table contains just two guests' do
context 'when they belong to the same group' do context 'when they belong to the same group' do
let(:table) { create_list(:guest, 2, affinity_group_list: ['family']) } let(:table) { create_list(:guest, 2, group: family) }
it { expect(calculator.send(:cohesion_penalty)).to eq(0) } it { expect(calculator.send(:cohesion_penalty)).to eq(0) }
end end
@ -31,8 +36,8 @@ module Tables
context 'when they belong to completely unrelated groups' do context 'when they belong to completely unrelated groups' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['family']), create(:guest, group: family),
create(:guest, affinity_group_list: ['friends']) create(:guest, group: friends)
] ]
end end
it { expect(calculator.send(:cohesion_penalty)).to eq(1) } it { expect(calculator.send(:cohesion_penalty)).to eq(1) }
@ -41,8 +46,8 @@ module Tables
context 'when they belong to groups at a distance of 1' do context 'when they belong to groups at a distance of 1' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['friends']), create(:guest, group: friends),
create(:guest, affinity_group_list: ['work']) create(:guest, group: work)
] ]
end end
@ -52,8 +57,8 @@ module Tables
context 'when they belong to groups at a distance of 2' do context 'when they belong to groups at a distance of 2' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['family']), create(:guest, group: family),
create(:guest, affinity_group_list: ['work']) create(:guest, group: work)
] ]
end end
@ -63,8 +68,8 @@ module Tables
context 'when they belong to groups at a distance of 3' do context 'when they belong to groups at a distance of 3' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['family']), create(:guest, group: family),
create(:guest, affinity_group_list: ['school']) create(:guest, group: school)
] ]
end end
@ -75,9 +80,9 @@ module Tables
context 'when the table contains three guests' do context 'when the table contains three guests' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['family']), create(:guest, group: family),
create(:guest, affinity_group_list: ['friends']), create(:guest, group: friends),
create(:guest, affinity_group_list: ['work']) create(:guest, group: work)
] ]
end end
@ -89,10 +94,10 @@ module Tables
context 'when the table contains four guests of different groups' do context 'when the table contains four guests of different groups' do
let(:table) do let(:table) do
[ [
create(:guest, affinity_group_list: ['family']), create(:guest, group: family),
create(:guest, affinity_group_list: ['friends']), create(:guest, group: friends),
create(:guest, affinity_group_list: ['work']), create(:guest, group: work),
create(:guest, affinity_group_list: ['school']) create(:guest, group: school)
] ]
end end
@ -105,8 +110,8 @@ module Tables
context 'when the table contains four guests of two evenly split groups' do context 'when the table contains four guests of two evenly split groups' do
let(:table) do let(:table) do
[ [
create_list(:guest, 2, affinity_group_list: ['family']), create_list(:guest, 2, group: family),
create_list(:guest, 2, affinity_group_list: ['friends']) create_list(:guest, 2, group: friends)
].flatten ].flatten
end end
@ -118,8 +123,8 @@ module Tables
context 'when the table contains six guests of two unevenly split groups' do context 'when the table contains six guests of two unevenly split groups' do
let(:table) do let(:table) do
[ [
create_list(:guest, 2, affinity_group_list: ['family']), create_list(:guest, 2, group: family),
create_list(:guest, 4, affinity_group_list: ['friends']) create_list(:guest, 4, group: friends)
].flatten ].flatten
end end
@ -131,9 +136,9 @@ module Tables
context 'when the table contains six guests of three evenly split groups' do context 'when the table contains six guests of three evenly split groups' do
let(:table) do let(:table) do
[ [
create_list(:guest, 2, affinity_group_list: ['family']), create_list(:guest, 2, group: family),
create_list(:guest, 2, affinity_group_list: ['friends']), create_list(:guest, 2, group: friends),
create_list(:guest, 2, affinity_group_list: ['work']) create_list(:guest, 2, group: work)
].flatten ].flatten
end end
@ -145,9 +150,9 @@ module Tables
context 'when the table contains six guests of three unevenly split groups' do context 'when the table contains six guests of three unevenly split groups' do
let(:table) do let(:table) do
[ [
create_list(:guest, 3, affinity_group_list: ['family']), create_list(:guest, 3, group: family),
create_list(:guest, 2, affinity_group_list: ['friends']), create_list(:guest, 2, group: friends),
create_list(:guest, 1, affinity_group_list: ['work']) create_list(:guest, 1, group: work)
].flatten ].flatten
end end