rasam 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edb330f4a39afa919a29872b4249db6d69508633
4
- data.tar.gz: 42ce22267bff052d5fbccd87503de4ea949a2035
3
+ metadata.gz: cefaa3715a0010c00504feb32a12fae7e5d4a538
4
+ data.tar.gz: 841cd1f623188c8eaf49a18e6ff540f1b703abbc
5
5
  SHA512:
6
- metadata.gz: 8e78d630959c5df719f4f591b5201bd6536fe260e97975218612fd747e7dccc3c0aac53bc36787d5dd693545efae1ae541d8132d8c50451c42516aec873e8336
7
- data.tar.gz: a57da9411abc696ae28bcb13b7bc0defb5f82d46cf3d722ec3eff699da9cb4209ead5c613e39b6d4ce822c17b3ad2ed311c6ebecf16cd30d1f5517473197d7e8
6
+ metadata.gz: 7bf0f4b37ca5b1b7ec31961723ffd48b4c7ddfd1ed82612da9b6b1ca161c181fd33c16e135e59507c20229527c6fab41468ffaa629c091c4a54e34ff19fb6c49
7
+ data.tar.gz: f5bbd8648953a8071926de7e7c5e012a1dfc6d8d266265d3cf48529c8d4932e0e0efafc1c7664f4d0961ed52416724b3fd0ce777d0e2644d50d1fe03e72a5f86
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ rasam
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.2
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # Rasam
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rasam`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
3
  Ranked pairs (RP) or the Tideman method is a voting system developed in 1987 by Nicolaus Tideman that selects a single winner using votes that express preferences. RP can also be used to create a sorted list of winners.
6
4
 
5
+ ## Console
6
+
7
+ To experiment with the code, run `bin/console` for an interactive prompt.
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -22,7 +24,80 @@ Or install it yourself as:
22
24
 
23
25
  ## Usage
24
26
 
25
- TODO: Write usage instructions here
27
+ Here is a simple script that uses the highline gem for command line interface to the gem. Just enter Salary <enter>, Stocks <enter>, Telecommuting <enter> and hit <enter><enter> when prompted for choices:
28
+
29
+ ```ruby
30
+ require 'highline/import'
31
+ require "pp"
32
+ require_relative '../lib/rasam'
33
+
34
+ include Rasam
35
+
36
+ def get_user_choice_for(pair)
37
+ choose do |menu|
38
+ menu.prompt = "Please choose your favorite: "
39
+
40
+ pair.each do |c|
41
+ menu.choice(c) do
42
+ say(c)
43
+ rationale = ask("Why? ")
44
+ say(rationale)
45
+
46
+ @pr.make_rational_choice(pair, c, rationale)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def display_score(options)
53
+ options.each do |option|
54
+ p "Score for #{option} : #{@pr.score_for(option)}"
55
+ end
56
+ end
57
+
58
+ options = ask("Enter your choices (or a blank line to quit):",
59
+ lambda { |ans| ans =~ /^-?\d+$/ ? Integer(ans) : ans} ) do |q|
60
+ q.gather = ""
61
+ end
62
+
63
+ @pr = PairRank.new(options)
64
+
65
+ def display_decisions
66
+ @pr.decisions.each do |d|
67
+ p d.to_s
68
+ end
69
+ end
70
+
71
+ pair = @pr.combination
72
+
73
+ loop do
74
+ p pair
75
+ break if pair.nil?
76
+ get_user_choice_for(pair)
77
+ pair = @pr.combination
78
+ end
79
+
80
+ display_decisions
81
+ display_score(options)
82
+
83
+ p 'Processing ties'
84
+
85
+ loop do
86
+ tie = @pr.tied_pair
87
+ if tie.empty?
88
+ break
89
+ else tie.empty?
90
+ p 'Handling a tie'
91
+
92
+ get_user_choice_for(tie)
93
+
94
+ display_decisions
95
+ display_score(options)
96
+ end
97
+ end
98
+ ```
99
+
100
+ You can find this script prank.rb in the scripts folder.
26
101
 
27
102
  ## Development
28
103
 
@@ -31,11 +106,25 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
31
106
  Run the test with color:
32
107
 
33
108
  ```ruby
34
- $ ruby -rminitest/pride test/pair_rank_test.rb
109
+ $ ruby -rminitest/pride test/pair_rank_test.rb --verbose
110
+ $ ruby -rminitest/pride test/pair_rank_simulator_test.rb --verbose
111
+ $ ruby -rminitest/pride test/combination_test.rb --verbose
35
112
  ```
36
113
 
114
+ To run all tests:
115
+
116
+ ```ruby
117
+ $ rake
118
+ ```
119
+
120
+ Default rake task will not run all the tests if you mix Test::Unit::TestCase and Minitest::Test. It will only run tests with Test::Unit::TestCase as it's parent. The coverage report gets clobbered if all the tests extend from Test::Unit::TestCase. So one of the test is extending from Minitest::Test to generate the coverage report.
121
+
37
122
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
38
123
 
124
+ ## Articles
125
+
126
+ [TDD Beyond Basics : Outside In Perspective] (https://rubyplus.com/articles/2531 'TDD Beyond Basics : Outside In Perspective')
127
+
39
128
  ## Contributing
40
129
 
41
130
  Bug reports and pull requests are welcome on GitHub at https://bitbucket.org/bparanj/rasam.
@@ -45,5 +134,4 @@ gem push rasam-0.1.0.gem
45
134
 
46
135
  ## License
47
136
 
48
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
49
-
137
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/lib/rasam.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "rasam/version"
2
- require 'forwardable'
3
2
 
4
3
  module Rasam
5
4
  # Value Object
@@ -20,61 +19,97 @@ module Rasam
20
19
  end
21
20
  end
22
21
 
22
+ class Combination
23
+ def initialize(options)
24
+ @list = options.combination(2).to_a
25
+ @index = -1
26
+ end
27
+
28
+ def pair
29
+ @index += 1
30
+ @list[@index]
31
+ end
32
+ end
33
+
23
34
  class PairRank
24
- attr_reader :combinations, :decisions
35
+ attr_reader :decisions
25
36
 
26
37
  def initialize(options)
38
+ @options = options
27
39
  @decisions = []
28
40
  @votes = Hash.new(0)
29
- @combinations = options.combination(2).to_a
41
+ @combination = Combination.new(@options)
30
42
  end
31
-
32
- def make(rational_choice)
33
- @decisions << rational_choice
34
- @votes[rational_choice.choice] += 1
43
+
44
+ def combinations
45
+ @options.combination(2).to_a
46
+ end
47
+
48
+ def combination
49
+ @combination.pair
35
50
  end
36
-
51
+
37
52
  def score_for(choice)
38
53
  @votes[choice]
39
54
  end
55
+
56
+ def tied_pair
57
+ return [] if zeros?
58
+
59
+ find_tie
60
+ end
61
+
62
+ def break_tie(pair, choice, criteria)
63
+ make_rational_choice(pair, choice, criteria)
64
+ end
65
+
66
+ def make_rational_choice(pair, choice, criteria)
67
+ rc = RationalChoice.new(pair, choice, criteria)
68
+ make(rc)
69
+ end
70
+
71
+ # :nocov:
72
+ private
40
73
 
41
- def rationale_for(choice)
42
- decision = @decisions.find{|x| x.choice == choice}
43
- decision.criteria
74
+ # All choices with 0 scores mean the Pair Ranking process has not begun
75
+ def zeros?
76
+ list = @options.collect{|c| score_for(c)}
77
+ list.uniq == [0]
44
78
  end
45
79
 
46
- def pair_for(choice)
47
- decision = @decisions.find{|x| x.choice == choice}
48
- decision.pair
80
+ def tie(combination)
81
+ first = score_for(combination[0])
82
+ second = score_for(combination[1])
83
+ first == second
49
84
  end
50
85
 
51
- def tied_pair
52
- result = []
53
- @combinations.each do |combination|
54
- first = score_for(combination[0])
55
- second = score_for(combination[1])
56
-
57
- if tie(first, second)
58
- result = combination
59
- break
60
- end
61
- end
62
- result
86
+ def make(rational_choice)
87
+ store(rational_choice)
88
+ vote_for(rational_choice)
63
89
  end
64
90
 
65
- def break_tie(pair, choice, criteria)
66
- make_rational_choice(pair, choice, criteria)
91
+ def has_tie?
92
+ !tied_pair.empty?
67
93
  end
68
94
 
69
- def make_rational_choice(pair, choice, criteria)
70
- rc = RationalChoice.new(pair, choice, criteria)
71
- make(rc)
95
+ def vote_for(rational_choice)
96
+ @votes[rational_choice.choice] += 1
72
97
  end
73
98
 
74
- private
99
+ # For display at the end of the Pair Ranking process
100
+ def store(rational_choice)
101
+ @decisions << rational_choice
102
+ end
75
103
 
76
- def tie(a, b)
77
- a == b
104
+ def find_tie
105
+ result = []
106
+ combinations.each do |combination|
107
+ if tie(combination)
108
+ result = combination
109
+ break
110
+ end
111
+ end
112
+ result
78
113
  end
79
114
  end
80
115
 
data/lib/rasam/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rasam
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
data/rasam.gemspec CHANGED
@@ -19,7 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.required_ruby_version = '>= 2.2.2'
23
+
22
24
  spec.add_development_dependency "bundler", "~> 1.10"
23
25
  spec.add_development_dependency "rake", "~> 10.0"
24
26
  spec.add_development_dependency "minitest", "~> 5.4"
27
+ spec.add_development_dependency "simplecov", "~> 0.10.0"
28
+ spec.add_development_dependency "highline", "~> 1.7"
25
29
  end
data/scripts/prank.rb ADDED
@@ -0,0 +1,69 @@
1
+ require 'highline/import'
2
+ require "pp"
3
+ require_relative '../lib/rasam'
4
+
5
+ include Rasam
6
+
7
+ def get_user_choice_for(pair)
8
+ choose do |menu|
9
+ menu.prompt = "Please choose your favorite: "
10
+
11
+ pair.each do |c|
12
+ menu.choice(c) do
13
+ say(c)
14
+ rationale = ask("Why? ")
15
+ say(rationale)
16
+
17
+ @pr.make_rational_choice(pair, c, rationale)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ def display_score(options)
24
+ options.each do |option|
25
+ p "Score for #{option} : #{@pr.score_for(option)}"
26
+ end
27
+ end
28
+
29
+ options = ask("Enter your choices (or a blank line to quit):",
30
+ lambda { |ans| ans =~ /^-?\d+$/ ? Integer(ans) : ans} ) do |q|
31
+ q.gather = ""
32
+ end
33
+
34
+ @pr = PairRank.new(options)
35
+
36
+ def display_decisions
37
+ @pr.decisions.each do |d|
38
+ p d.to_s
39
+ end
40
+ end
41
+
42
+ pair = @pr.combination
43
+
44
+ loop do
45
+ p pair
46
+ break if pair.nil?
47
+ get_user_choice_for(pair)
48
+ pair = @pr.combination
49
+ end
50
+
51
+ display_decisions
52
+ display_score(options)
53
+
54
+ p 'Processing ties'
55
+
56
+ loop do
57
+ tie = @pr.tied_pair
58
+ if tie.empty?
59
+ break
60
+ else tie.empty?
61
+ p 'Handling a tie'
62
+
63
+ get_user_choice_for(tie)
64
+
65
+ display_decisions
66
+ display_score(options)
67
+ end
68
+ end
69
+
data/todo.txt CHANGED
@@ -1,2 +1,11 @@
1
- 1. Use highline library to simulate a user session.
2
- 2. Update the existing rational choices with the tie break results. This will update the existing decisions array.
1
+ 1. Demo using realistic example for job offer negotiation:
2
+
3
+ Salary
4
+ Stocks
5
+ Bonus
6
+ Signon Bonus
7
+ Vacation
8
+ Telecommuting
9
+
10
+ 2. Buying a car.
11
+ 3. Choosing a job.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bala Paranj
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-06-27 00:00:00.000000000 Z
11
+ date: 2015-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: highline
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
55
83
  description: Select a single winner using votes that express preferences. This can
56
84
  also be used to create a sorted list of winners
57
85
  email:
@@ -61,6 +89,8 @@ extensions: []
61
89
  extra_rdoc_files: []
62
90
  files:
63
91
  - ".gitignore"
92
+ - ".ruby-gemset"
93
+ - ".ruby-version"
64
94
  - ".travis.yml"
65
95
  - Gemfile
66
96
  - LICENSE.txt
@@ -71,6 +101,7 @@ files:
71
101
  - lib/rasam.rb
72
102
  - lib/rasam/version.rb
73
103
  - rasam.gemspec
104
+ - scripts/prank.rb
74
105
  - todo.txt
75
106
  homepage: https://bitbucket.org/bparanj/rasam
76
107
  licenses:
@@ -84,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
115
  requirements:
85
116
  - - ">="
86
117
  - !ruby/object:Gem::Version
87
- version: '0'
118
+ version: 2.2.2
88
119
  required_rubygems_version: !ruby/object:Gem::Requirement
89
120
  requirements:
90
121
  - - ">="
@@ -92,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
123
  version: '0'
93
124
  requirements: []
94
125
  rubyforge_project:
95
- rubygems_version: 2.2.2
126
+ rubygems_version: 2.4.6
96
127
  signing_key:
97
128
  specification_version: 4
98
129
  summary: Pair Rank a given list of items.