Adapt discomfort calculator to use groups instead of affinity tags #79
| @ -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 | ||||||
|  | |||||||
| @ -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? | ||||||
|  | |||||||
| @ -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 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user