sapor 0.4.1 → 0.4.2
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.
- checksums.yaml +4 -4
- data/lib/sapor.rb +1 -0
- data/lib/sapor/poll.rb +2 -2
- data/lib/sapor/regional_data/european_union_portugal.rb +1 -1
- data/lib/sapor/regional_data/romania.rb +107 -0
- data/lib/sapor/single_district_proportional.rb +20 -7
- data/sapor.gemspec +1 -1
- data/spec/unit/romania_spec.rb +69 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9db9878d88eba52cd75bd216c3fd4b98f72786aff78b781cd76b4dc9d0d68c6
|
4
|
+
data.tar.gz: f5ee7d583d0728b24adf93f1728398043ce77649694f328b1aac1830c80a6e91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a1dbf105b97217abfaa3cb2065be93f931e08fb670539cab5f35dcdbc74e9a224b7dbc0b6cdaebb5406f04723f33658c40a7be17aceee83a06c127f6c33d0f4
|
7
|
+
data.tar.gz: 21f6c3faca8b6300bfcc1800683f56de35cc8046b46bc2739b3a1a2641b64241456cac25e74933a893143aa57d66069a695ee8c34a897b2a0e5b713020ec8749
|
data/lib/sapor.rb
CHANGED
@@ -118,6 +118,7 @@ require 'sapor/regional_data/portugal_with_a_ch_and_il_without_paf'
|
|
118
118
|
require 'sapor/regional_data/portugal_with_a_without_paf'
|
119
119
|
require 'sapor/regional_data/portugal_with_ch_and_il_without_paf'
|
120
120
|
require 'sapor/regional_data/portugal_without_paf'
|
121
|
+
require 'sapor/regional_data/romania'
|
121
122
|
require 'sapor/regional_data/slovakia'
|
122
123
|
require 'sapor/regional_data/slovenia'
|
123
124
|
require 'sapor/regional_data/spain'
|
data/lib/sapor/poll.rb
CHANGED
@@ -89,8 +89,8 @@ module Sapor
|
|
89
89
|
Estonia.instance, Finland.instance, FinlandWithSin.instance,
|
90
90
|
France.instance, Greece.instance, Hungary.instance, Iceland.instance,
|
91
91
|
IcelandWithJ.instance, Ireland.instance, Latvia.instance,
|
92
|
-
Luxembourg.instance, Netherlands.instance,
|
93
|
-
Slovenia.instance, Spain.instance, Sweden.instance,
|
92
|
+
Luxembourg.instance, Netherlands.instance, Romania.instance,
|
93
|
+
Slovakia.instance, Slovenia.instance, Spain.instance, Sweden.instance,
|
94
94
|
Sweden20140914.instance, UnitedKingdom.instance,
|
95
95
|
UnitedKingdomWithBrexit.instance, UnitedKingdomWithBrexitAndChuk.instance,
|
96
96
|
UnitedKingdomWithTig.instance, Utopia.instance]).map do |area|
|
@@ -51,7 +51,7 @@ module Sapor
|
|
51
51
|
'Coligação Democrática Unitária (GUE/NGL)'],
|
52
52
|
['CDS–Partido Popular (EPP)',
|
53
53
|
'Partido Social Democrata (EPP)'],
|
54
|
-
['Chega (
|
54
|
+
['Chega (ID)'],
|
55
55
|
['Partido Socialista (S&D)'],
|
56
56
|
['LIVRE (Greens/EFA)',
|
57
57
|
'Pessoas–Animais–Natureza (Greens/EFA)']].freeze
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#
|
2
|
+
# Statistical Analysis of Polling Results (SAPoR)
|
3
|
+
# Copyright (C) 2020 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
4
|
+
#
|
5
|
+
# This file is part of SAPoR.
|
6
|
+
#
|
7
|
+
# SAPoR is free software: you can redistribute it and/or modify it under the
|
8
|
+
# terms of the GNU General Public License as published by the Free Software
|
9
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
10
|
+
# version.
|
11
|
+
#
|
12
|
+
# SAPoR is distributed in the hope that it will be useful, but WITHOUT ANY
|
13
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
14
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You can find a copy of the GNU General Public License in /doc/gpl.txt
|
17
|
+
#
|
18
|
+
|
19
|
+
module Sapor
|
20
|
+
#
|
21
|
+
# The regional data for Romania.
|
22
|
+
#
|
23
|
+
class Romania < Area
|
24
|
+
include Singleton
|
25
|
+
|
26
|
+
def area_code
|
27
|
+
'RO'
|
28
|
+
end
|
29
|
+
|
30
|
+
def coalitions
|
31
|
+
COALITIONS
|
32
|
+
end
|
33
|
+
|
34
|
+
def no_of_seats
|
35
|
+
NO_OF_SEATS
|
36
|
+
end
|
37
|
+
|
38
|
+
def population_size
|
39
|
+
POPULATION_SIZE
|
40
|
+
end
|
41
|
+
|
42
|
+
def seats(simulation)
|
43
|
+
electoral_system.project(simulation)
|
44
|
+
end
|
45
|
+
|
46
|
+
def threshold
|
47
|
+
THRESHOLD
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
A2020_COALITION = 'Alianța 2020 USR-PLUS'.freeze
|
53
|
+
ALDE_PARTY = 'Partidul Alianța Liberalilor și Democraților'.freeze
|
54
|
+
# PLUS_PARTY = 'Partidul Libertății, Unității și Solidarității'.freeze
|
55
|
+
PMP_PARTY = 'Partidul Mișcarea Populară'.freeze
|
56
|
+
PNL_PARTY = 'Partidul Național Liberal'.freeze
|
57
|
+
PRO_PARTY = 'PRO România'.freeze
|
58
|
+
PSD_PARTY = 'Partidul Social Democrat'.freeze
|
59
|
+
UDMR_PARTY = 'Uniunea Democrată Maghiară din România'.freeze
|
60
|
+
# USR_PARTY = 'Uniunea Salvați România'.freeze
|
61
|
+
|
62
|
+
COALITIONS = [[A2020_COALITION, ALDE_PARTY, PMP_PARTY, PNL_PARTY],
|
63
|
+
[A2020_COALITION, ALDE_PARTY, PMP_PARTY, PNL_PARTY,
|
64
|
+
UDMR_PARTY],
|
65
|
+
[A2020_COALITION, ALDE_PARTY, PNL_PARTY],
|
66
|
+
[A2020_COALITION, ALDE_PARTY, PNL_PARTY, UDMR_PARTY],
|
67
|
+
[A2020_COALITION, PMP_PARTY],
|
68
|
+
[A2020_COALITION, PMP_PARTY, PNL_PARTY],
|
69
|
+
[A2020_COALITION, PMP_PARTY, PNL_PARTY, UDMR_PARTY],
|
70
|
+
[A2020_COALITION, PNL_PARTY],
|
71
|
+
[A2020_COALITION, PNL_PARTY, UDMR_PARTY],
|
72
|
+
[ALDE_PARTY, PMP_PARTY, PNL_PARTY, UDMR_PARTY],
|
73
|
+
[ALDE_PARTY, PNL_PARTY, UDMR_PARTY],
|
74
|
+
[ALDE_PARTY, PRO_PARTY, PSD_PARTY],
|
75
|
+
[ALDE_PARTY, PSD_PARTY],
|
76
|
+
[PMP_PARTY, PNL_PARTY],
|
77
|
+
[PMP_PARTY, PNL_PARTY, UDMR_PARTY],
|
78
|
+
[PNL_PARTY, UDMR_PARTY],
|
79
|
+
# [ALDE_PARTY, PLUS_PARTY, PMP_PARTY, PNL_PARTY, UDMR_PARTY,
|
80
|
+
# USR_PARTY],
|
81
|
+
[PNL_PARTY],
|
82
|
+
[PRO_PARTY, PSD_PARTY]].freeze
|
83
|
+
|
84
|
+
NO_OF_SEATS = 312
|
85
|
+
|
86
|
+
# Voter turnout on 11 December 2016
|
87
|
+
# Source: Web page with the official results of the elections of 11 December
|
88
|
+
# 2016, downloaded on 22 February 2020,
|
89
|
+
# https://en.wikipedia.org/wiki/2016_Romanian_legislative_election
|
90
|
+
POPULATION_SIZE = 7_047_384
|
91
|
+
|
92
|
+
THRESHOLD = 0.05
|
93
|
+
COALITION_LIST_THRESHOLD = 0.08
|
94
|
+
COALITION_LISTS = [A2020_COALITION].freeze
|
95
|
+
MINORITY_LISTS = [UDMR_PARTY].freeze
|
96
|
+
|
97
|
+
def electoral_system
|
98
|
+
if @electoral_system.nil?
|
99
|
+
@electoral_system = SingleDistrictProportional.new(
|
100
|
+
NO_OF_SEATS, DhondtDenominators, THRESHOLD, 0, false,
|
101
|
+
COALITION_LIST_THRESHOLD, COALITION_LISTS, MINORITY_LISTS
|
102
|
+
)
|
103
|
+
end
|
104
|
+
@electoral_system
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
#
|
3
3
|
# Statistical Analysis of Polling Results (SAPoR)
|
4
4
|
# Copyright (C) 2020 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
@@ -22,16 +22,24 @@ module Sapor
|
|
22
22
|
# Class representing a proportional electoral system with only one district.
|
23
23
|
#
|
24
24
|
class SingleDistrictProportional
|
25
|
-
def initialize(no_of_seats, denominators_class, threshold = 0, bonus = 0
|
25
|
+
def initialize(no_of_seats, denominators_class, threshold = 0, bonus = 0,
|
26
|
+
other_eligible = true, coalition_list_threshold = 1,
|
27
|
+
coalition_lists = [], minority_lists = [])
|
26
28
|
@no_of_seats = no_of_seats
|
27
29
|
@denominators_class = denominators_class
|
28
30
|
@threshold = threshold
|
29
31
|
@bonus = bonus
|
32
|
+
@other_eligible = other_eligible
|
33
|
+
@coalition_list_threshold = coalition_list_threshold
|
34
|
+
@coalition_lists = coalition_lists
|
35
|
+
@minority_lists = minority_lists
|
30
36
|
end
|
31
37
|
|
32
38
|
def project(simulation)
|
33
|
-
|
34
|
-
|
39
|
+
votes_sum = simulation.values.inject(:+).to_f
|
40
|
+
threshold = votes_sum * @threshold
|
41
|
+
coalition_list_threshold = votes_sum * @coalition_list_threshold
|
42
|
+
quotients = quotients(simulation, threshold, coalition_list_threshold)
|
35
43
|
sorted_quotients = quotients.sort { |a, b| b.last <=> a.last }
|
36
44
|
seats = sorted_quotients.map(&:first).slice(0, @no_of_seats)
|
37
45
|
result = create_empty_result(simulation)
|
@@ -46,7 +54,7 @@ module Sapor
|
|
46
54
|
simulation.each_key do |choice|
|
47
55
|
result[choice] = 0
|
48
56
|
end
|
49
|
-
result[simulation.
|
57
|
+
result[simulation.max_by(&:last)[0]] = @bonus
|
50
58
|
result[OTHER] = 0
|
51
59
|
result
|
52
60
|
end
|
@@ -61,10 +69,15 @@ module Sapor
|
|
61
69
|
end
|
62
70
|
end
|
63
71
|
|
64
|
-
def quotients(votes, threshold)
|
72
|
+
def quotients(votes, threshold, coalition_list_threshold)
|
65
73
|
quotients = []
|
66
74
|
votes.each_pair do |choice, new_value|
|
67
|
-
next if
|
75
|
+
next if choice == OTHER && !@other_eligible
|
76
|
+
next unless @minority_lists.include?(choice) ||
|
77
|
+
@coalition_lists.include?(choice) &&
|
78
|
+
new_value >= coalition_list_threshold ||
|
79
|
+
!@coalition_lists.include?(choice) &&
|
80
|
+
new_value >= threshold
|
68
81
|
@denominators_class.get(@no_of_seats).each do |d|
|
69
82
|
quotients << [choice, new_value.to_f / d]
|
70
83
|
end
|
data/sapor.gemspec
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Statistical Analysis of Polling Results (SAPoR)
|
4
|
+
# Copyright (C) 2020 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
5
|
+
#
|
6
|
+
# This file is part of SAPoR.
|
7
|
+
#
|
8
|
+
# SAPoR is free software: you can redistribute it and/or modify it under the
|
9
|
+
# terms of the GNU General Public License as published by the Free Software
|
10
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
11
|
+
# version.
|
12
|
+
#
|
13
|
+
# SAPoR is distributed in the hope that it will be useful, but WITHOUT ANY
|
14
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
15
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You can find a copy of the GNU General Public License in /doc/gpl.txt
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'spec_helper'
|
21
|
+
|
22
|
+
describe Sapor::Romania, '#area_code' do
|
23
|
+
it 'returns RO as the area code' do
|
24
|
+
expect(Sapor::Romania.instance.area_code).to eq('RO')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Sapor::Romania, '#no_of_seats' do
|
29
|
+
it 'returns 312 as the number of seats' do
|
30
|
+
expect(Sapor::Romania.instance.no_of_seats).to eq(312)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Sapor::Romania, '#population_size' do
|
35
|
+
it 'returns a population size of 7,047,384' do
|
36
|
+
expect(Sapor::Romania.instance.population_size).to \
|
37
|
+
eq(7_047_384)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Sapor::Romania, '#seats' do
|
42
|
+
it 'calculates the number of seats for the election of 2014' do
|
43
|
+
results = { 'Partidul Social Democrat' => 3_204_864,
|
44
|
+
'Partidul Național Liberal' => 1_412_377,
|
45
|
+
'Uniunea Salvați România' => 625_154,
|
46
|
+
'Uniunea Democrată Maghiară din România' => 435_969,
|
47
|
+
'Partidul Alianța Liberalilor și Democraților' => 396_386,
|
48
|
+
'Partidul Mișcarea Populară' => 376_891,
|
49
|
+
'Partidul România Unită' => 196_397,
|
50
|
+
'Partidul România Mare' => 73_264,
|
51
|
+
'Partidul Ecologist Român' => 62_414,
|
52
|
+
'Alianța Noastră România' => 61_206,
|
53
|
+
'Partidul Socialist Român' => 24_580,
|
54
|
+
'Partida Romilor „Pro Europa”' => 13_126 }
|
55
|
+
seats = Sapor::Romania.instance.seats(results)
|
56
|
+
expect(seats['Partidul Social Democrat']).to eq(154 + 2)
|
57
|
+
expect(seats['Partidul Național Liberal']).to eq(69 - 1)
|
58
|
+
expect(seats['Uniunea Salvați România']).to eq(30)
|
59
|
+
expect(seats['Uniunea Democrată Maghiară din România']).to eq(21)
|
60
|
+
expect(seats['Partidul Alianța Liberalilor și Democraților']).to eq(20 - 1)
|
61
|
+
expect(seats['Partidul Mișcarea Populară']).to eq(18)
|
62
|
+
expect(seats['Partidul România Unită']).to eq(0)
|
63
|
+
expect(seats['Partidul România Mare']).to eq(0)
|
64
|
+
expect(seats['Partidul Ecologist Român']).to eq(0)
|
65
|
+
expect(seats['Alianța Noastră România']).to eq(0)
|
66
|
+
expect(seats['Partidul Socialist Român']).to eq(0)
|
67
|
+
expect(seats['Partida Romilor „Pro Europa”']).to eq(0)
|
68
|
+
end
|
69
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sapor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Filip van Laenen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: SAPoR
|
14
14
|
email:
|
@@ -208,6 +208,7 @@ files:
|
|
208
208
|
- lib/sapor/regional_data/portugal_with_a_without_paf.rb
|
209
209
|
- lib/sapor/regional_data/portugal_with_ch_and_il_without_paf.rb
|
210
210
|
- lib/sapor/regional_data/portugal_without_paf.rb
|
211
|
+
- lib/sapor/regional_data/romania.rb
|
211
212
|
- lib/sapor/regional_data/slovakia.rb
|
212
213
|
- lib/sapor/regional_data/slovenia.rb
|
213
214
|
- lib/sapor/regional_data/spain-20160626.psv
|
@@ -320,6 +321,7 @@ files:
|
|
320
321
|
- spec/unit/pseudorandom_multirange_enumerator_spec.rb
|
321
322
|
- spec/unit/referendum_polychotomy_spec.rb
|
322
323
|
- spec/unit/representatives_polychotomy_spec.rb
|
324
|
+
- spec/unit/romania_spec.rb
|
323
325
|
- spec/unit/slovakia_spec.rb
|
324
326
|
- spec/unit/slovenia_spec.rb
|
325
327
|
- spec/unit/spain_spec.rb
|
@@ -445,6 +447,7 @@ test_files:
|
|
445
447
|
- spec/unit/pseudorandom_multirange_enumerator_spec.rb
|
446
448
|
- spec/unit/referendum_polychotomy_spec.rb
|
447
449
|
- spec/unit/representatives_polychotomy_spec.rb
|
450
|
+
- spec/unit/romania_spec.rb
|
448
451
|
- spec/unit/slovakia_spec.rb
|
449
452
|
- spec/unit/slovenia_spec.rb
|
450
453
|
- spec/unit/spain_spec.rb
|