Class: Equalshares::Instance

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

Overview

A parsed pabulib instance.

Mirrors the JS { meta, projects, votes, approvers } shape:

meta      - Hash{String => String} key/value metadata (includes "budget", "vote_type")
projects  - Hash{String => Hash{String => String}} project_id => raw row fields (incl "cost", "name")
votes     - Hash{String => Hash{String => String}} voter_id => raw row fields
approvers - Hash{String => Array<String>} project_id => list of voter_ids approving it

Constant Summary collapse

ARRAY_INDEX =

Replicate the iteration order of JavaScript's Object.keys, which the original tool relies on (C = Object.keys(projects), N = Object.keys(votes)): integer "array index" keys come first in ascending numeric order, followed by all other keys in insertion order. Project/voter IDs are typically numeric strings, so this ordering affects tie stability (e.g. greedy utilitarian completion).

/\A(?:0|[1-9]\d*)\z/
UINT32_MAX =
(2**32) - 1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(meta:, projects:, votes:, approvers:, scores: nil) ⇒ Instance

scores is nil for approval instances; for cardinal ballots (vote_type "scoring"/"cumulative") it is Hash=> Hash{voter_id => score string}.



16
17
18
19
20
21
22
# File 'lib/equalshares/instance.rb', line 16

def initialize(meta:, projects:, votes:, approvers:, scores: nil)
  @meta = meta
  @projects = projects
  @votes = votes
  @approvers = approvers
  @scores = scores
end

Instance Attribute Details

#approversObject (readonly)

Returns the value of attribute approvers.



12
13
14
# File 'lib/equalshares/instance.rb', line 12

def approvers
  @approvers
end

#metaObject (readonly)

Returns the value of attribute meta.



12
13
14
# File 'lib/equalshares/instance.rb', line 12

def meta
  @meta
end

#projectsObject (readonly)

Returns the value of attribute projects.



12
13
14
# File 'lib/equalshares/instance.rb', line 12

def projects
  @projects
end

#scoresObject (readonly)

Returns the value of attribute scores.



12
13
14
# File 'lib/equalshares/instance.rb', line 12

def scores
  @scores
end

#votesObject (readonly)

Returns the value of attribute votes.



12
13
14
# File 'lib/equalshares/instance.rb', line 12

def votes
  @votes
end

Class Method Details

.js_key_order(keys) ⇒ Object



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

def self.js_key_order(keys)
  indices, others = keys.partition { |k| ARRAY_INDEX.match?(k) && k.to_i < UINT32_MAX }
  indices.sort_by(&:to_i) + others
end

Instance Method Details

#budgetObject



43
44
45
# File 'lib/equalshares/instance.rb', line 43

def budget
  @meta["budget"]
end

#cardinal?Boolean

True for cardinal (scoring/cumulative) instances that carry per-voter scores.

Returns:

  • (Boolean)


25
26
27
# File 'lib/equalshares/instance.rb', line 25

def cardinal?
  !@scores.nil?
end

#project_idsObject

Project IDs (JS: Object.keys(projects))



39
40
41
# File 'lib/equalshares/instance.rb', line 39

def project_ids
  @project_ids ||= self.class.js_key_order(@projects.keys)
end

#vote_typeObject



29
30
31
# File 'lib/equalshares/instance.rb', line 29

def vote_type
  @meta["vote_type"]
end

#voter_idsObject

Voter IDs (JS: Object.keys(votes))



34
35
36
# File 'lib/equalshares/instance.rb', line 34

def voter_ids
  @voter_ids ||= self.class.js_key_order(@votes.keys)
end