meekster 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,151 @@
1
+ require File.expand_path("../lib/meekster", File.dirname(__FILE__))
2
+
3
+ describe "meekster" do
4
+
5
+ describe "simplest election" do
6
+ it "elects the candidate" do
7
+ c1 = Meekster::Candidate.new
8
+ c1.name = "Adam"
9
+ candidates = [c1]
10
+
11
+ b1 = Meekster::Ballot.new
12
+ b1.ranking = [c1]
13
+ ballots = [b1]
14
+
15
+ election = Meekster::Election.new
16
+ election.candidates = candidates
17
+ election.ballots = ballots
18
+ election.seats = 1
19
+
20
+ election.run!
21
+
22
+ c1.state.should == :elected
23
+ end
24
+ end
25
+
26
+ describe "wikipedia example STV election" do
27
+ before(:each) do
28
+ candidates = [
29
+ @oranges = Meekster::Candidate.new('Oranges'),
30
+ @pears = Meekster::Candidate.new('Pears'),
31
+ @chocolate = Meekster::Candidate.new('Chocolate'),
32
+ @strawberries = Meekster::Candidate.new('Stawberries'),
33
+ @sweets = Meekster::Candidate.new('Sweets')
34
+ ]
35
+
36
+ ballots = [
37
+ Meekster::Ballot.new([@oranges]),
38
+ Meekster::Ballot.new([@oranges]),
39
+ Meekster::Ballot.new([@oranges]),
40
+ Meekster::Ballot.new([@oranges]),
41
+ Meekster::Ballot.new([@pears, @oranges]),
42
+ Meekster::Ballot.new([@pears, @oranges]),
43
+ Meekster::Ballot.new([@chocolate, @strawberries]),
44
+ Meekster::Ballot.new([@chocolate, @strawberries]),
45
+ Meekster::Ballot.new([@chocolate, @strawberries]),
46
+ Meekster::Ballot.new([@chocolate, @strawberries]),
47
+ Meekster::Ballot.new([@chocolate, @strawberries]),
48
+ Meekster::Ballot.new([@chocolate, @strawberries]),
49
+ Meekster::Ballot.new([@chocolate, @strawberries]),
50
+ Meekster::Ballot.new([@chocolate, @strawberries]),
51
+ Meekster::Ballot.new([@chocolate, @sweets]),
52
+ Meekster::Ballot.new([@chocolate, @sweets]),
53
+ Meekster::Ballot.new([@chocolate, @sweets]),
54
+ Meekster::Ballot.new([@chocolate, @sweets]),
55
+ Meekster::Ballot.new([@strawberries]),
56
+ Meekster::Ballot.new([@sweets])
57
+ ]
58
+
59
+ election = Meekster::Election.new
60
+ election.candidates = candidates
61
+ election.ballots = ballots
62
+ election.seats = 3
63
+
64
+ election.run!
65
+ end
66
+
67
+ it "elects the correct candidates" do
68
+ @chocolate.state.should == :elected
69
+ @oranges.state.should == :elected
70
+ @strawberries.state.should == :elected
71
+ end
72
+
73
+ it "rejects the correct candidates" do
74
+ @pears.state.should == :defeated
75
+ @sweets.state.should == :defeated
76
+ end
77
+ end
78
+
79
+ # http://code.google.com/p/droop/wiki/Droop
80
+ describe "sample elections from Droop" do
81
+ describe "42" do
82
+ before(:all) do
83
+ @election = Meekster::Election.new(
84
+ :ballot_file => Meekster::BallotFile.new(
85
+ :filename => File.expand_path("ballot_files/42.blt", File.dirname(__FILE__))
86
+ )
87
+ )
88
+ @election.run!
89
+ end
90
+
91
+ it "elects the correct candidates" do
92
+ @election.candidates.find{|c| c.name == 'Castor'}.state.should == :elected
93
+ @election.candidates.find{|c| c.name == 'Castor'}.votes.should be_within(0.000000001).of(2.000000004)
94
+
95
+ @election.candidates.find{|c| c.name == 'Helen'}.state.should == :elected
96
+ @election.candidates.find{|c| c.name == 'Helen'}.votes.should be_within(0.000000001).of(2.000000000)
97
+ end
98
+
99
+ it "rejects the correct candidates" do
100
+ @election.candidates.find{|c| c.name == 'Pollux'}.state.should == :defeated
101
+ end
102
+
103
+ it "calculates votes for the rejected candidates correctly" do
104
+ pending('Need to fix final round') do
105
+ @election.candidates.find{|c| c.name == 'Pollux'}.votes.should be_within(0.000000001).of(0.000000000)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe "Anderston-City-2007" do
111
+ before(:all) do
112
+ @election = Meekster::Election.new(
113
+ :ballot_file => Meekster::BallotFile.new(
114
+ :filename => File.expand_path("ballot_files/Anderston-City-2007.blt", File.dirname(__FILE__))
115
+ )
116
+ )
117
+ @election.run!
118
+ end
119
+
120
+ it "elects the correct candidates" do
121
+ @election.candidates.find{|c| c.name == 'Nina Baker'}.state.should == :elected
122
+ @election.candidates.find{|c| c.name == 'Nina Baker'}.votes.should be_within(0.00001).of(1298.307340419)
123
+
124
+ @election.candidates.find{|c| c.name == 'Philip Braat'}.state.should == :elected
125
+ @election.candidates.find{|c| c.name == 'Philip Braat'}.votes.should be_within(0.00001).of(1297.105615751)
126
+
127
+ @election.candidates.find{|c| c.name == 'Craig MacKay'}.state.should == :elected
128
+ @election.candidates.find{|c| c.name == 'Craig MacKay'}.votes.should be_within(0.00001).of(1280.501790024)
129
+
130
+ @election.candidates.find{|c| c.name == 'Gordon Matheson'}.state.should == :elected
131
+ @election.candidates.find{|c| c.name == 'Gordon Matheson'}.votes.should be_within(0.00001).of(1325.225745098)
132
+ end
133
+
134
+ it "rejects the correct candidates" do
135
+ ['Erin Boyle', 'Dave Holladay', 'Akhtar Khan', 'Ann Laird', 'Peter Murray'].each do |name|
136
+ @election.candidates.find{|c| c.name == name}.state.should == :defeated
137
+ end
138
+ end
139
+
140
+ it "calculates votes for the rejected candidates correctly" do
141
+ pending('Need to fix final round')
142
+ end
143
+ end
144
+ end
145
+
146
+ it "calculates the final quota"
147
+ it "calculates the final number of votes"
148
+ it "calculates the final residual"
149
+ it "calculates the final surplus"
150
+
151
+ end
@@ -0,0 +1,22 @@
1
+ require './lib/meekster/round'
2
+ require 'bigdecimal'
3
+
4
+ describe Meekster::Round do
5
+
6
+ describe ".round_up_to_nine_decimal_places" do
7
+ it "rounds to the same value when tenth and later decimal places are zero" do
8
+ Meekster::Round.round_up_to_nine_decimal_places(BigDecimal('1.1234567890')).should == BigDecimal('1.123456789')
9
+ end
10
+
11
+ it "rounds up when tenth decimal place is present" do
12
+ Meekster::Round.round_up_to_nine_decimal_places(BigDecimal('1.2222222221')).should == BigDecimal('1.2222222230')
13
+ end
14
+ end
15
+
16
+ describe ".truncate_to_nine_decimal_places" do
17
+ it "removes tenth decimal and more" do
18
+ Meekster::Round.truncate_to_nine_decimal_places(BigDecimal('1.3333333337777')).should == BigDecimal('1.333333333')
19
+ end
20
+ end
21
+
22
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meekster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Mear
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 2.9.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 2.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.2
41
+ description: Meekster implements a Meek Single Transferable Vote (STV) voting system,
42
+ as described in the Proportional Representation Foundation's Reference Meek Rule.
43
+ email: chris@feedmechocolate.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - README.md
51
+ - Rakefile
52
+ - lib/meekster.rb
53
+ - lib/meekster/ballot.rb
54
+ - lib/meekster/ballot_file.rb
55
+ - lib/meekster/candidate.rb
56
+ - lib/meekster/election.rb
57
+ - lib/meekster/round.rb
58
+ - lib/meekster/version.rb
59
+ - meekster.gemspec
60
+ - spec/ballot_file_spec.rb
61
+ - spec/ballot_files/42.blt
62
+ - spec/ballot_files/Anderston-City-2007.blt
63
+ - spec/meekster_spec.rb
64
+ - spec/round_spec.rb
65
+ homepage: https://github.com/chrismear/meekster
66
+ licenses: []
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.0.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: An implementation of the Meek STV election voting system.
88
+ test_files:
89
+ - spec/ballot_file_spec.rb
90
+ - spec/ballot_files/42.blt
91
+ - spec/ballot_files/Anderston-City-2007.blt
92
+ - spec/meekster_spec.rb
93
+ - spec/round_spec.rb