Class: Equalshares::Election

Inherits:
Object
  • Object
show all
Defined in:
lib/equalshares/election.rb

Overview

A numeric view of an instance for a given accuracy. It exposes the voters, projects and supporters together with the per-project cost, the budget and the per-voter utilities, all converted to the right numeric type (exact Rational for "fractions", Float for "floats"). This centralises the setup that every rule previously repeated, and provides the float-based statistics used for reporting.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instance, params = Params.new) ⇒ Election

Returns a new instance of Election.



12
13
14
15
16
17
18
# File 'lib/equalshares/election.rb', line 12

def initialize(instance, params = Params.new)
  @instance = instance
  @params = params
  @exact = params.accuracy == "fractions"
  @costs = instance.project_ids.to_h { |c| [c, numeric(instance.projects[c]["cost"])] }
  @float_costs = instance.project_ids.to_h { |c| [c, Float(instance.projects[c]["cost"])] }
end

Instance Attribute Details

#costsObject (readonly)

Per-project cost in the accuracy's numeric type, as a Hash=> Numeric.



41
42
43
# File 'lib/equalshares/election.rb', line 41

def costs
  @costs
end

#float_costsObject (readonly)

Per-project cost as floats, as a Hash=> Float (for statistics and the cost/comparison bookkeeping that the equalshares.net tool always does in floats).



45
46
47
# File 'lib/equalshares/election.rb', line 45

def float_costs
  @float_costs
end

#instanceObject (readonly)

Returns the value of attribute instance.



10
11
12
# File 'lib/equalshares/election.rb', line 10

def instance
  @instance
end

#paramsObject (readonly)

Returns the value of attribute params.



10
11
12
# File 'lib/equalshares/election.rb', line 10

def params
  @params
end

Class Method Details

.rational_of(value) ⇒ Object

Exact rational from a cost/budget string, matching fraction.js's decimal handling ("5000" -> 5000, "5000.5" -> 10001/2).



71
72
73
74
75
# File 'lib/equalshares/election.rb', line 71

def self.rational_of(value)
  Rational(value.to_s)
rescue ArgumentError
  Float(value).to_r
end

Instance Method Details

#approversObject



28
29
30
# File 'lib/equalshares/election.rb', line 28

def approvers
  instance.approvers
end

#budgetObject



47
48
49
# File 'lib/equalshares/election.rb', line 47

def budget
  @budget ||= numeric(instance.budget)
end

#exact?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/equalshares/election.rb', line 36

def exact?
  @exact
end

#float_budgetObject



51
52
53
# File 'lib/equalshares/election.rb', line 51

def float_budget
  @float_budget ||= Float(instance.budget)
end

#numeric(value) ⇒ Object

Convert a cost/budget/score string to the accuracy's numeric type.



65
66
67
# File 'lib/equalshares/election.rb', line 65

def numeric(value)
  @exact ? self.class.rational_of(value) : Float(value)
end

#project_idsObject



24
25
26
# File 'lib/equalshares/election.rb', line 24

def project_ids
  instance.project_ids
end

#statistics(winners) ⇒ Object



60
61
62
# File 'lib/equalshares/election.rb', line 60

def statistics(winners)
  Statistics.gather(voter_ids, @float_costs, instance.approvers, winners)
end

#supporters(project_id) ⇒ Object



32
33
34
# File 'lib/equalshares/election.rb', line 32

def supporters(project_id)
  instance.approvers[project_id]
end

#utilities(project_id) ⇒ Object

Per-project voter utilities for cardinal/ordinal ballots: { voter_id => Numeric }.



56
57
58
# File 'lib/equalshares/election.rb', line 56

def utilities(project_id)
  (instance.scores[project_id] || {}).transform_values { |score| numeric(score) }
end

#voter_idsObject



20
21
22
# File 'lib/equalshares/election.rb', line 20

def voter_ids
  instance.voter_ids
end