rodders 3.0.1 → 3.1.0

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.
data/Gemfile CHANGED
@@ -14,3 +14,10 @@ group :development do
14
14
  gem "jeweler", "~> 1.6.4"
15
15
  gem "simplecov"
16
16
  end
17
+
18
+ group :development, :test do
19
+ gem 'debugger'
20
+ end
21
+
22
+ gem 'activesupport'
23
+ gem 'i18n'
data/Gemfile.lock CHANGED
@@ -1,6 +1,17 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ activesupport (3.2.8)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ columnize (0.3.6)
8
+ debugger (1.1.3)
9
+ columnize (>= 0.3.1)
10
+ debugger-linecache (~> 1.1.1)
11
+ debugger-ruby_core_source (~> 1.1.2)
12
+ debugger-linecache (1.1.1)
13
+ debugger-ruby_core_source (>= 1.1.1)
14
+ debugger-ruby_core_source (1.1.2)
4
15
  diff-lcs (1.1.3)
5
16
  git (1.2.5)
6
17
  i18n (0.6.0)
@@ -32,7 +43,10 @@ PLATFORMS
32
43
  ruby
33
44
 
34
45
  DEPENDENCIES
46
+ activesupport
35
47
  bundler (~> 1.0.0)
48
+ debugger
49
+ i18n
36
50
  jeweler (~> 1.6.4)
37
51
  money
38
52
  rspec (~> 2.9.0)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.1
1
+ 3.1.0
data/lib/fixed_odds.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'money'
2
+ require 'active_support/all'
2
3
 
3
4
  # Represents fixed odds used in gambling and betting. Supports fractional,
4
5
  # moneyline and decimal representations. Can calculate the profit
@@ -58,11 +59,11 @@ class FixedOdds
58
59
  # @return (see FixedOdds.from_s)
59
60
  def FixedOdds.fractional_odds fractional
60
61
  raise %{could not parse "#{fractional}" as fractional odds} unless self.fractional_odds?(fractional)
61
- return new(1.to_r) if fractional == 'evens' or fractional == 'even money'
62
+ return new(1.to_r) if fractional.inquiry.evens? or fractional == 'even money'
62
63
 
63
64
  o = /(?<numerator>\d+)(\/|-to-)(?<denominator>\d+)/.match fractional
64
65
  r = Rational o[:numerator], o[:denominator]
65
- r = r.reciprocal if fractional.end_with? ' on'
66
+ r = 1 / r if fractional.ends_with? ' on'
66
67
  new r
67
68
  end
68
69
 
@@ -80,9 +81,12 @@ class FixedOdds
80
81
  # @return (see FixedOdds.from_s)
81
82
  def FixedOdds.moneyline_odds moneyline
82
83
  raise %{could not parse "#{moneyline}" as moneyline odds} unless self.moneyline_odds?(moneyline)
83
- sign = moneyline[0]
84
- if sign == '+' then new(Rational(moneyline, 100))
85
- else new(Rational(100, -moneyline.to_i))
84
+
85
+ case moneyline[0]
86
+ when '+'
87
+ new(Rational(moneyline, 100))
88
+ else
89
+ new(Rational(100, -moneyline.to_i))
86
90
  end
87
91
  end
88
92
 
@@ -158,14 +162,4 @@ class FixedOdds
158
162
  def <=> other
159
163
  other.fractional_odds <=> @fractional_odds
160
164
  end
161
- end
162
-
163
- class Rational
164
- # calculates the reciprocal
165
- # @example
166
- # Rational(2/3).reciprocal #=> Rational(3/2)
167
- # @return [Rational] the reciprocal
168
- def reciprocal
169
- 1 / self
170
- end
171
165
  end
@@ -4,7 +4,7 @@
4
4
  class MutuallyExclusiveCollection
5
5
  # create a new collection with the given odds
6
6
  # @param [Array<FixedOdds>] mutually_exclusive_outcome_odds the odds for all the mutually exclusive outcomes
7
- def initialize(mutually_exclusive_outcome_odds)
7
+ def initialize mutually_exclusive_outcome_odds
8
8
  @mutually_exclusive_outcome_odds = mutually_exclusive_outcome_odds.sort
9
9
  end
10
10
 
@@ -43,31 +43,27 @@ class MutuallyExclusiveCollection
43
43
  # @return [Number] the bookmaker's return rate as a percentage
44
44
  def bookmakers_return_rate
45
45
  fs = fractions
46
- fs.any? ? 1 - fs.reduce(:*) / fs.reduce(:+) : 0
46
+ 1 - fs.reduce(:*) / fs.reduce(:+) if fs.any?
47
47
  end
48
48
 
49
49
  # hash of the odds and what percentage of the total stake should go on each
50
50
  # @return [Hash<FixedOdds, Number>] hash of odds to percentages
51
51
  def percentages
52
- hash = {}
53
- @mutually_exclusive_outcome_odds.each {|odds| hash[odds] = 1 / odds.fractional_odds / sum_inverse_outcome }
54
- hash
52
+ @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = 1 / odds.fractional_odds / sum_inverse_outcome }
55
53
  end
56
54
 
57
55
  # hash of the odds and what stakes to put on each given a total stake
58
56
  # @param [Money] total_stake the money to distribute on the outcomes
59
57
  # @return [Hash<FixedOdds, Money>] hash of odds to stakes
60
58
  def stakes_for_total_stake total_stake
61
- hash = {}
62
- @mutually_exclusive_outcome_odds.each {|odds| hash[odds] = total_stake / odds.fractional_odds / sum_inverse_outcome }
63
- hash
59
+ @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = total_stake / odds.fractional_odds / sum_inverse_outcome }
64
60
  end
65
61
 
66
62
  # hash of the odds and the stakes needed to make the specified profit
67
63
  # @param (see #stakes_for_total_stake)
68
64
  # @return (see #stakes_for_total_stake)
69
65
  def stakes_for_profit desired_profit
70
- stakes_for_total_stake(stake_to_profit(desired_profit))
66
+ stakes_for_total_stake stake_to_profit desired_profit
71
67
  end
72
68
 
73
69
  # the stake needed to win the desired profit
@@ -97,6 +93,6 @@ class MutuallyExclusiveCollection
97
93
  end
98
94
 
99
95
  def fractions
100
- @mutually_exclusive_outcome_odds.collect {|o| o.fractional_odds }
96
+ @mutually_exclusive_outcome_odds.collect &:fractional_odds
101
97
  end
102
98
  end
data/rodders.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "rodders"
8
- s.version = "3.0.1"
8
+ s.version = "3.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nigel Lowry"]
12
- s.date = "2012-05-12"
12
+ s.date = "2012-11-11"
13
13
  s.description = "Converts between fractional, decimal and moneyline odds for betting and gambling. Calculates how much can be won on a given stake."
14
14
  s.email = "nigel-lowry@ultra.eclipse.co.uk"
15
15
  s.extra_rdoc_files = [
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
36
36
  s.homepage = "http://github.com/nigel-lowry/rodders"
37
37
  s.licenses = ["MIT"]
38
38
  s.require_paths = ["lib"]
39
- s.rubygems_version = "1.8.23"
39
+ s.rubygems_version = "1.8.24"
40
40
  s.summary = "Fixed odds betting library"
41
41
 
42
42
  if s.respond_to? :specification_version then
@@ -44,26 +44,35 @@ Gem::Specification.new do |s|
44
44
 
45
45
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
46
  s.add_runtime_dependency(%q<money>, [">= 0"])
47
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
48
+ s.add_runtime_dependency(%q<i18n>, [">= 0"])
47
49
  s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
48
50
  s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
49
51
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
52
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
51
53
  s.add_development_dependency(%q<simplecov>, [">= 0"])
54
+ s.add_development_dependency(%q<debugger>, [">= 0"])
52
55
  else
53
56
  s.add_dependency(%q<money>, [">= 0"])
57
+ s.add_dependency(%q<activesupport>, [">= 0"])
58
+ s.add_dependency(%q<i18n>, [">= 0"])
54
59
  s.add_dependency(%q<rspec>, ["~> 2.9.0"])
55
60
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
56
61
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
62
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
63
  s.add_dependency(%q<simplecov>, [">= 0"])
64
+ s.add_dependency(%q<debugger>, [">= 0"])
59
65
  end
60
66
  else
61
67
  s.add_dependency(%q<money>, [">= 0"])
68
+ s.add_dependency(%q<activesupport>, [">= 0"])
69
+ s.add_dependency(%q<i18n>, [">= 0"])
62
70
  s.add_dependency(%q<rspec>, ["~> 2.9.0"])
63
71
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
64
72
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
73
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
66
74
  s.add_dependency(%q<simplecov>, [">= 0"])
75
+ s.add_dependency(%q<debugger>, [">= 0"])
67
76
  end
68
77
  end
69
78
 
@@ -16,13 +16,13 @@ describe "FixedOdds" do
16
16
  it "does not change the input string with 'against'" do
17
17
  value = '4/1 against'
18
18
  FixedOdds.fractional_odds(value)
19
- value.end_with?('against').should == true
19
+ value.end_with?('against').should be
20
20
  end
21
21
 
22
22
  it "does not modify the input string with 'on'" do
23
23
  value = '4/1 on'
24
24
  FixedOdds.fractional_odds(value)
25
- value.end_with?('on').should == true
25
+ value.end_with?('on').should be
26
26
  end
27
27
 
28
28
  specify { FixedOdds.fractional_odds('4/1 against').should == FixedOdds.fractional_odds('4/1') }
@@ -80,12 +80,12 @@ describe "FixedOdds" do
80
80
  )
81
81
  end
82
82
 
83
- specify { FixedOdds.moneyline_odds('+400').profit_on_stake(Money.parse '£100').should == Money.parse('£400') }
84
- specify { FixedOdds.moneyline_odds('+100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
83
+ specify { FixedOdds.moneyline_odds('+400').profit_on_stake('£100'.to_money).should == '£400'.to_money }
84
+ specify { FixedOdds.moneyline_odds('+100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
85
85
 
86
- specify { FixedOdds.moneyline_odds('-400').profit_on_stake(Money.parse '£400').should == Money.parse('£100') }
87
- specify { FixedOdds.moneyline_odds('-100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
88
- specify { FixedOdds.moneyline_odds('+100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
86
+ specify { FixedOdds.moneyline_odds('-400').profit_on_stake('£400'.to_money).should == '£100'.to_money }
87
+ specify { FixedOdds.moneyline_odds('-100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
88
+ specify { FixedOdds.moneyline_odds('+100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
89
89
  end
90
90
 
91
91
  describe ".decimal_odds" do
@@ -98,9 +98,9 @@ describe "FixedOdds" do
98
98
  )
99
99
  end
100
100
 
101
- specify { FixedOdds.decimal_odds('2').profit_on_stake(Money.parse '£1').should == Money.parse('£1') }
102
- specify { FixedOdds.decimal_odds('5').profit_on_stake(Money.parse '£1').should == Money.parse('£4') }
103
- specify { FixedOdds.decimal_odds('1.25').profit_on_stake(Money.parse '£4').should == Money.parse('£1') }
101
+ specify { FixedOdds.decimal_odds('2').profit_on_stake('£1'.to_money).should == '£1'.to_money }
102
+ specify { FixedOdds.decimal_odds('5').profit_on_stake('£1'.to_money).should == '£4'.to_money }
103
+ specify { FixedOdds.decimal_odds('1.25').profit_on_stake('£4'.to_money).should == '£1'.to_money }
104
104
  end
105
105
 
106
106
  describe ".from_s" do
@@ -25,7 +25,7 @@ describe "MutuallyExclusiveCollection" do
25
25
  @bookmaker = MutuallyExclusiveCollection.new []
26
26
  end
27
27
 
28
- specify { @bookmaker.bookmakers_return_rate.should == 0 }
28
+ specify { @bookmaker.bookmakers_return_rate.should be_nil }
29
29
  end
30
30
 
31
31
  context "decimal odds arbitrage" do
@@ -48,7 +48,7 @@ describe "MutuallyExclusiveCollection" do
48
48
  specify { @bookmaker1.bookmakers_return_rate.should be_within(0.0001).of(0.0534) }
49
49
  specify { @bookmaker2.bookmakers_return_rate.should be_within(0.0001).of(0.0478) }
50
50
 
51
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£100').should == Money.parse('£4.63') }
51
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£100'.to_money).should == '£4.63'.to_money }
52
52
  specify { @bookmaker_vulnerable_to_arbitrage.profit_percentage.should be_within(0.001).of(0.046) }
53
53
  end
54
54
 
@@ -64,7 +64,7 @@ describe "MutuallyExclusiveCollection" do
64
64
 
65
65
  specify { @bookmaker_vulnerable_to_arbitrage.should be_arbitrageable }
66
66
  its(:profit_percentage) { should be_within(0.001).of(0.2) }
67
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£500').should == Money.parse('£100') }
67
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£500'.to_money).should == '£100'.to_money }
68
68
  end
69
69
 
70
70
  context "more than two mutually exclusive events" do
@@ -96,27 +96,27 @@ describe "MutuallyExclusiveCollection" do
96
96
  total = Money.parse '£500'
97
97
  amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_total_stake total
98
98
  amounts.should have(3).items
99
- amounts[@odds1].should == Money.parse('£396.14')
100
- amounts[@odds2].should == Money.parse('£73.57')
101
- amounts[@odds3].should == Money.parse('£30.29')
99
+ amounts[@odds1].should == '£396.14'.to_money
100
+ amounts[@odds2].should == '£73.57'.to_money
101
+ amounts[@odds3].should == '£30.29'.to_money
102
102
  amounts.values.reduce(:+).should == total
103
103
  end
104
104
  end
105
105
 
106
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£500').should == Money.parse('£14.98') }
106
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£500'.to_money).should == '£14.98'.to_money }
107
107
 
108
108
  describe "#stakes_for_profit" do
109
109
  it "gives the right amounts" do
110
- amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_profit Money.parse '£750'
110
+ amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_profit '£750'.to_money
111
111
  amounts.should have(3).items
112
- amounts[@odds1].should == Money.parse('£19833.33')
113
- amounts[@odds2].should == Money.parse('£3683.33')
114
- amounts[@odds3].should == Money.parse('£1516.67')
115
- amounts.values.reduce(:+).should == Money.parse('£25033.33')
112
+ amounts[@odds1].should == '£19833.33'.to_money
113
+ amounts[@odds2].should == '£3683.33'.to_money
114
+ amounts[@odds3].should == '£1516.67'.to_money
115
+ amounts.values.reduce(:+).should == '£25033.33'.to_money
116
116
  end
117
117
  end
118
118
 
119
- specify { @bookmaker_vulnerable_to_arbitrage.stake_to_profit(Money.parse '£750').should == Money.parse('£25033.33') }
119
+ specify { @bookmaker_vulnerable_to_arbitrage.stake_to_profit('£750'.to_money).should == '£25033.33'.to_money }
120
120
  end
121
121
 
122
122
  context "different events with same odds" do
@@ -128,7 +128,7 @@ describe "MutuallyExclusiveCollection" do
128
128
  end
129
129
 
130
130
  specify { @bookmaker_vulnerable_to_arbitrage.should be_arbitrageable }
131
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£100').should == Money.parse('£650') }
131
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£100'.to_money).should == '£650'.to_money }
132
132
 
133
133
  describe "#percentages" do
134
134
  it "gives the percentages to put on each bet" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodders
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-12 00:00:00.000000000 Z
12
+ date: 2012-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: i18n
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: rspec
32
64
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +139,22 @@ dependencies:
107
139
  - - ! '>='
108
140
  - !ruby/object:Gem::Version
109
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: debugger
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
110
158
  description: Converts between fractional, decimal and moneyline odds for betting and
111
159
  gambling. Calculates how much can be won on a given stake.
112
160
  email: nigel-lowry@ultra.eclipse.co.uk
@@ -146,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
194
  version: '0'
147
195
  segments:
148
196
  - 0
149
- hash: -1158855232544155326
197
+ hash: 437333735277840555
150
198
  required_rubygems_version: !ruby/object:Gem::Requirement
151
199
  none: false
152
200
  requirements:
@@ -155,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
203
  version: '0'
156
204
  requirements: []
157
205
  rubyforge_project:
158
- rubygems_version: 1.8.23
206
+ rubygems_version: 1.8.24
159
207
  signing_key:
160
208
  specification_version: 3
161
209
  summary: Fixed odds betting library