bb_analytics 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +53 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +60 -0
- data/README.md +43 -0
- data/README.rdoc +0 -0
- data/Rakefile +30 -0
- data/bb_analytics.gemspec +26 -0
- data/bb_analytics.rdoc +5 -0
- data/bin/bb_analytics +132 -0
- data/lib/bb_analytics/models/baseball_player.rb +45 -0
- data/lib/bb_analytics/models/data_store.rb +61 -0
- data/lib/bb_analytics/models/importer.rb +58 -0
- data/lib/bb_analytics/models/stats_for_year.rb +218 -0
- data/lib/bb_analytics/version.rb +3 -0
- data/lib/bb_analytics.rb +24 -0
- data/results.html +472 -0
- data/spec/models/baseball_player_spec.rb +44 -0
- data/spec/models/importer_spec.rb +117 -0
- data/spec/models/stats_for_year_spec.rb +258 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/Batting-07-12.csv +1 -0
- data/spec/support/Master-small.csv +1 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a3ac7a2bb7cef6a44843224c7b86d9bf7222295
|
4
|
+
data.tar.gz: 96301c15766b1a5f3e15bef1970f8b4daddc0bc0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d8a3ffef20afa037a0cb796e32b750f6a06a229154301a4967534c38cf65e579c5ed1c2ebaced40abb713242ba7d1419b6e3d5d73fb0f619baed2c4108a1e27
|
7
|
+
data.tar.gz: f82167185a8430410817183d30b3c9032135b9bd9d65719a5e619d3bdc5a1088b2a3bc13f29442c035892ecf3e97e4848629fa0db56857fa299dc89ee367e9df
|
data/.gitignore
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
coverage.data
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
19
|
+
#
|
20
|
+
# * Create a file at ~/.gitignore
|
21
|
+
# * Include files you want ignored
|
22
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
23
|
+
#
|
24
|
+
# After doing this, these files will be ignored in all your git projects,
|
25
|
+
# saving you from having to 'pollute' every project you touch with them
|
26
|
+
#
|
27
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
28
|
+
#
|
29
|
+
# For MacOS:
|
30
|
+
#
|
31
|
+
#.DS_Store
|
32
|
+
|
33
|
+
# For TextMate
|
34
|
+
#*.tmproj
|
35
|
+
#tmtags
|
36
|
+
|
37
|
+
# For emacs:
|
38
|
+
#*~
|
39
|
+
#\#*
|
40
|
+
#.\#*
|
41
|
+
|
42
|
+
# For vim:
|
43
|
+
#*.swp
|
44
|
+
|
45
|
+
# For redcar:
|
46
|
+
#.redcar
|
47
|
+
|
48
|
+
# For rubinius:
|
49
|
+
#*.rbc
|
50
|
+
|
51
|
+
# For rvm:
|
52
|
+
.ruby-gemset
|
53
|
+
.ruby-version
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bb_analytics (0.0.1)
|
5
|
+
gli (= 2.9.0)
|
6
|
+
sqlite3
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
aruba (0.5.4)
|
12
|
+
childprocess (>= 0.3.6)
|
13
|
+
cucumber (>= 1.1.1)
|
14
|
+
rspec-expectations (>= 2.7.0)
|
15
|
+
builder (3.2.2)
|
16
|
+
childprocess (0.5.1)
|
17
|
+
ffi (~> 1.0, >= 1.0.11)
|
18
|
+
cucumber (1.3.11)
|
19
|
+
builder (>= 2.1.2)
|
20
|
+
diff-lcs (>= 1.1.3)
|
21
|
+
gherkin (~> 2.12)
|
22
|
+
multi_json (>= 1.7.5, < 2.0)
|
23
|
+
multi_test (>= 0.0.2)
|
24
|
+
diff-lcs (1.2.5)
|
25
|
+
docile (1.1.3)
|
26
|
+
ffi (1.9.3)
|
27
|
+
gherkin (2.12.2)
|
28
|
+
multi_json (~> 1.3)
|
29
|
+
gli (2.9.0)
|
30
|
+
json (1.8.1)
|
31
|
+
multi_json (1.8.4)
|
32
|
+
multi_test (0.0.3)
|
33
|
+
rake (10.1.1)
|
34
|
+
rdoc (4.1.1)
|
35
|
+
json (~> 1.4)
|
36
|
+
rspec (2.14.1)
|
37
|
+
rspec-core (~> 2.14.0)
|
38
|
+
rspec-expectations (~> 2.14.0)
|
39
|
+
rspec-mocks (~> 2.14.0)
|
40
|
+
rspec-core (2.14.8)
|
41
|
+
rspec-expectations (2.14.5)
|
42
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
43
|
+
rspec-mocks (2.14.6)
|
44
|
+
simplecov (0.8.2)
|
45
|
+
docile (~> 1.1.0)
|
46
|
+
multi_json
|
47
|
+
simplecov-html (~> 0.8.0)
|
48
|
+
simplecov-html (0.8.0)
|
49
|
+
sqlite3 (1.3.9)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
ruby
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
aruba
|
56
|
+
bb_analytics!
|
57
|
+
rake
|
58
|
+
rdoc
|
59
|
+
rspec
|
60
|
+
simplecov
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
# bb_analytics
|
3
|
+
|
4
|
+
A simple baseball analytics tool built on top of the GLI platform, which mean it follows
|
5
|
+
the standard CLI pattern of taking commands (like git).
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
```shell
|
10
|
+
$ gem install bb_analytics
|
11
|
+
```
|
12
|
+
bb_analytics requires sqlite3, so you'll have to meet the prerquisites for that install.
|
13
|
+
|
14
|
+
## How-to
|
15
|
+
|
16
|
+
Typing `$ bb_analytics help` will render a list of commands and options:
|
17
|
+
|
18
|
+
```shell
|
19
|
+
NAME
|
20
|
+
bb_analytics - A simple baseball analytics tool
|
21
|
+
|
22
|
+
SYNOPSIS
|
23
|
+
bb_analytics [global options] command [command options] [arguments...]
|
24
|
+
|
25
|
+
VERSION
|
26
|
+
0.0.1
|
27
|
+
|
28
|
+
GLOBAL OPTIONS
|
29
|
+
--help - Show this message
|
30
|
+
--version - Display the program version
|
31
|
+
|
32
|
+
COMMANDS
|
33
|
+
clear - Clear all imported data
|
34
|
+
help - Shows a list of commands or help for one command
|
35
|
+
import - Import a data file
|
36
|
+
most_improved - List the most improved players for a supplied time period
|
37
|
+
team_slugging_percentage - Team slugging percentage
|
38
|
+
triple_crown_winner - Find the tripple crown winner for a given year
|
39
|
+
```
|
40
|
+
Before querying for analytics, you'll have to import data from csv. The import command
|
41
|
+
tolerates csv files that define player identities and files that define yearly statistics.
|
42
|
+
|
43
|
+
For help with any command, just type `bb_analytics help <command name>`.
|
data/README.rdoc
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'cucumber'
|
6
|
+
require 'cucumber/rake/task'
|
7
|
+
Rake::RDocTask.new do |rd|
|
8
|
+
rd.main = "README.rdoc"
|
9
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
10
|
+
rd.title = 'Your application title'
|
11
|
+
end
|
12
|
+
|
13
|
+
spec = eval(File.read('bb_analytics.gemspec'))
|
14
|
+
|
15
|
+
Gem::PackageTask.new(spec) do |pkg|
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rspec/core'
|
19
|
+
require 'rspec/core/rake_task'
|
20
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
21
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Code coverage detail"
|
25
|
+
task :simplecov do
|
26
|
+
ENV['COVERAGE'] = "true"
|
27
|
+
Rake::Task['spec'].execute
|
28
|
+
end
|
29
|
+
|
30
|
+
task :default => :spec
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','bb_analytics','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'bb_analytics'
|
5
|
+
s.version = BbAnalytics::VERSION
|
6
|
+
s.author = 'Kevin Beddingfield'
|
7
|
+
s.description = "a simple baseball analytics tool"
|
8
|
+
s.email = 'kevin.beddingfield@gmail.com'
|
9
|
+
s.homepage = 'http://mambasystems.net'
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.summary = 'A simple baseball analytics tool'
|
12
|
+
s.files = `git ls-files`.split(" ")
|
13
|
+
s.require_paths << 'lib'
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.extra_rdoc_files = ['README.rdoc','bb_analytics.rdoc']
|
16
|
+
s.rdoc_options << '--title' << 'bb_analytics' << '--main' << 'README.rdoc' << '-ri'
|
17
|
+
s.bindir = 'bin'
|
18
|
+
s.executables << 'bb_analytics'
|
19
|
+
s.add_development_dependency('rake')
|
20
|
+
s.add_development_dependency('rdoc')
|
21
|
+
s.add_development_dependency('aruba')
|
22
|
+
s.add_development_dependency('rspec')
|
23
|
+
s.add_development_dependency('simplecov')
|
24
|
+
s.add_runtime_dependency('sqlite3')
|
25
|
+
s.add_runtime_dependency('gli','2.9.0')
|
26
|
+
end
|
data/bb_analytics.rdoc
ADDED
data/bin/bb_analytics
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
|
4
|
+
=begin
|
5
|
+
begin # XXX: Remove this begin/rescue before distributing your app
|
6
|
+
require 'bb_analytics'
|
7
|
+
rescue LoadError
|
8
|
+
STDERR.puts "In development, you need to use `bundle exec bin/bb_analytics` to run your app"
|
9
|
+
STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
|
10
|
+
STDERR.puts "Feel free to remove this message from bin/bb_analytics now"
|
11
|
+
exit 64
|
12
|
+
end
|
13
|
+
=end
|
14
|
+
|
15
|
+
include GLI::App
|
16
|
+
|
17
|
+
program_desc 'A simple baseball analytics tool'
|
18
|
+
|
19
|
+
version BbAnalytics::VERSION
|
20
|
+
|
21
|
+
desc 'Import a data file'
|
22
|
+
arg_name '"file location"'
|
23
|
+
command :import do |c|
|
24
|
+
c.action do |global_options,options,args|
|
25
|
+
args.each do |arg|
|
26
|
+
puts "reading #{arg}"
|
27
|
+
importer = Importer.new(arg)
|
28
|
+
|
29
|
+
puts "loading players..."
|
30
|
+
importer.save_baseball_players
|
31
|
+
|
32
|
+
puts "checking for stats..."
|
33
|
+
importer.save_stats_for_year
|
34
|
+
|
35
|
+
puts "import of #{arg} complete!"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Clear all imported data'
|
41
|
+
command :clear do |c|
|
42
|
+
c.action do |global_options,options,args|
|
43
|
+
DataStore.instance.clear_data
|
44
|
+
puts "import data is cleared!"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Find the tripple crown winner for a given year'
|
49
|
+
command :triple_crown_winner do |c|
|
50
|
+
c.desc 'the year to evaluate'
|
51
|
+
c.default_value '2012'
|
52
|
+
c.arg_name 'year'
|
53
|
+
c.flag [:y,:year]
|
54
|
+
c.desc 'minimum at bats'
|
55
|
+
c.default_value '600'
|
56
|
+
c.arg_name 'min-at-bats'
|
57
|
+
c.flag [:'min-at-bats']
|
58
|
+
c.action do |global_options,options,args|
|
59
|
+
winner = StatsForYear.find_triple_crown_winner(options[:year], options[:'min-at-bats'])
|
60
|
+
if winner.nil?
|
61
|
+
puts "there was no triple crown winner in #{options[:year]}"
|
62
|
+
else
|
63
|
+
player = winner.baseball_player
|
64
|
+
puts "#{player.first_name} #{player.last_name} won the triple crown in #{options[:year]}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
desc 'List the most improved players for a supplied time period'
|
70
|
+
command :most_improved do |c|
|
71
|
+
c.desc 'accepted values are batting_average and fantasy_points'
|
72
|
+
c.default_value 'batting_average'
|
73
|
+
c.flag :category
|
74
|
+
c.desc 'starting year (inclusive)'
|
75
|
+
c.default_value '2009'
|
76
|
+
c.flag :starting_year
|
77
|
+
c.desc 'ending year (inclusive)'
|
78
|
+
c.default_value '2010'
|
79
|
+
c.flag :ending_year
|
80
|
+
c.action do |global_options,options,args|
|
81
|
+
if options[:category] == 'batting_average'
|
82
|
+
player_ids = StatsForYear.most_improved_batting_average options[:starting_year], options[:ending_year]
|
83
|
+
elsif options[:category] == 'fantasy_points'
|
84
|
+
player_ids = StatsForYear.most_improved_fantasy_points options[:starting_year], options[:ending_year]
|
85
|
+
else
|
86
|
+
puts 'Please specify a valid category (batting_average, fantasy_points)'
|
87
|
+
return
|
88
|
+
end
|
89
|
+
if player_ids
|
90
|
+
player_ids.each do |player_id|
|
91
|
+
player = BaseballPlayer.find_by_external_id player_id
|
92
|
+
puts "#{player.first_name} #{player.last_name}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
desc 'Team slugging percentage'
|
99
|
+
command :team_slugging_percentage do |c|
|
100
|
+
c.desc 'the year to evaluate'
|
101
|
+
c.default_value '2007'
|
102
|
+
c.arg_name 'year'
|
103
|
+
c.flag [:y,:year]
|
104
|
+
c.desc 'team abbreviation'
|
105
|
+
c.default_value 'OAK'
|
106
|
+
c.arg_name 'team'
|
107
|
+
c.flag [:'team']
|
108
|
+
c.action do |global_options,options,args|
|
109
|
+
teammates = StatsForYear.find_team_for_year options[:year], options[:team]
|
110
|
+
teammates.each do |teammate|
|
111
|
+
player = teammate.baseball_player
|
112
|
+
puts "#{player.first_name} #{player.last_name} - slugging percentage: #{'%.3f' % (teammate.slugging_percentage * 0.001)}" if teammate.slugging_percentage.present?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
pre do |global,command,options,args|
|
118
|
+
Dir.mkdir("#{ENV['HOME']}/.bb_analytics") if !Dir.entries("#{ENV['HOME']}").include?('.bb_analytics');
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
post do |global,command,options,args|
|
123
|
+
# Post logic here
|
124
|
+
# Use skips_post before a command to skip this
|
125
|
+
# block on that command only
|
126
|
+
end
|
127
|
+
|
128
|
+
on_error do |exception|
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
132
|
+
exit run(ARGV)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class BaseballPlayer
|
2
|
+
attr_accessor :external_id, :birth_year, :first_name, :last_name
|
3
|
+
|
4
|
+
def save
|
5
|
+
# first see if we can update an existing record
|
6
|
+
DataStore.instance.db.execute("select * from baseball_players where external_id = ?",
|
7
|
+
[self.external_id]) do |row|
|
8
|
+
DataStore.instance.db.execute "update baseball_players set birth_year = ?, first_name = ?, last_name = ? where external_id = ?",
|
9
|
+
[(self.birth_year.present? ? self.birth_year : row[1]),
|
10
|
+
(self.first_name.present? ? self.first_name : row[2]),
|
11
|
+
(self.last_name.present? ? self.last_name : row[3]),
|
12
|
+
self.external_id]
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
# if not, just insert
|
17
|
+
DataStore.instance.db.execute "insert into baseball_players values (?,?,?,?)",
|
18
|
+
[self.external_id,
|
19
|
+
self.birth_year,
|
20
|
+
self.first_name,
|
21
|
+
self.last_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def reload
|
25
|
+
DataStore.instance.db.execute("select * from baseball_players where external_id = ?",
|
26
|
+
[self.external_id]) do |row|
|
27
|
+
self.birth_year = row[1]
|
28
|
+
self.first_name = row[2]
|
29
|
+
self.last_name = row[3]
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.find_by_external_id external_id
|
35
|
+
player = BaseballPlayer.new
|
36
|
+
DataStore.instance.db.execute("select * from baseball_players where external_id = ?",
|
37
|
+
[external_id]) do |row|
|
38
|
+
player.external_id = row[0]
|
39
|
+
player.birth_year = row[1]
|
40
|
+
player.first_name = row[2]
|
41
|
+
player.last_name = row[3]
|
42
|
+
end
|
43
|
+
player
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
class DataStore
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
attr_accessor :db
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.setup_db
|
11
|
+
end
|
12
|
+
|
13
|
+
def db=(db)
|
14
|
+
# try and create tables - will error if they exist (which is okay)
|
15
|
+
@db = db
|
16
|
+
begin
|
17
|
+
@db.execute <<-SQL
|
18
|
+
create table baseball_players (
|
19
|
+
external_id varchar(50),
|
20
|
+
birth_year int,
|
21
|
+
first_name varchar(50),
|
22
|
+
last_name varchar(50)
|
23
|
+
);
|
24
|
+
SQL
|
25
|
+
@db.execute <<-SQL
|
26
|
+
create table stats_for_years (
|
27
|
+
player_external_id varchar(50),
|
28
|
+
year int,
|
29
|
+
team varchar(3),
|
30
|
+
games int,
|
31
|
+
at_bats int,
|
32
|
+
runs int,
|
33
|
+
hits int,
|
34
|
+
doubles int,
|
35
|
+
triples int,
|
36
|
+
home_runs int,
|
37
|
+
runs_batted_in int,
|
38
|
+
stolen_bases int,
|
39
|
+
caught_stealing int,
|
40
|
+
batting_average int,
|
41
|
+
slugging_percentage int,
|
42
|
+
fantasy_points int
|
43
|
+
);
|
44
|
+
SQL
|
45
|
+
rescue
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def clear_data
|
50
|
+
File.delete(db_location) rescue nil
|
51
|
+
#self.setup_db
|
52
|
+
end
|
53
|
+
|
54
|
+
def setup_db
|
55
|
+
self.db = SQLite3::Database.new self.db_location rescue nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def db_location
|
59
|
+
"#{ENV['HOME']}/.bb_analytics/bba.db"
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
class Importer
|
4
|
+
attr_accessor :csv
|
5
|
+
|
6
|
+
def initialize(csv_file=nil)
|
7
|
+
if csv_file
|
8
|
+
@csv ||= {}
|
9
|
+
CSV.foreach(csv_file, headers: true, header_converters: :symbol, converters: :all) do |row|
|
10
|
+
@csv[row.fields[0]] ||= []
|
11
|
+
@csv[row.fields[0]] << Hash[row.headers[1..-1].zip(row.fields[1..-1])]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def save_baseball_players
|
17
|
+
@csv.keys.map do |key|
|
18
|
+
csv[key].each do |bp|
|
19
|
+
player = BaseballPlayer.new
|
20
|
+
player.external_id = key
|
21
|
+
player.birth_year = bp[:birthyear]
|
22
|
+
player.first_name = bp[:namefirst]
|
23
|
+
player.last_name = bp[:namelast]
|
24
|
+
player.save
|
25
|
+
player
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def save_stats_for_year
|
31
|
+
@csv.keys.each do |key|
|
32
|
+
csv[key].each do |year|
|
33
|
+
stats = StatsForYear.new
|
34
|
+
stats.player_external_id = key
|
35
|
+
stats.year = year[:yearid]
|
36
|
+
stats.team = year[:teamid]
|
37
|
+
stats.games = year[:g]
|
38
|
+
stats.at_bats = year[:ab]
|
39
|
+
stats.runs = year[:r]
|
40
|
+
stats.hits = year[:h]
|
41
|
+
stats.doubles = year[:'2b']
|
42
|
+
stats.triples = year[:'3b']
|
43
|
+
stats.home_runs = year[:hr]
|
44
|
+
stats.runs_batted_in = year[:rbi]
|
45
|
+
stats.stolen_bases = year[:sb]
|
46
|
+
stats.caught_stealing = year[:cs]
|
47
|
+
|
48
|
+
stats.calculate_batting_average!
|
49
|
+
stats.calculate_slugging_percentage!
|
50
|
+
stats.calculate_fantasy_points!
|
51
|
+
|
52
|
+
stats.save if stats.year.present?
|
53
|
+
stats
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|