diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..5b0150e842 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Ignore test-related files +/coverage.data +/coverage/ \ No newline at end of file diff --git a/README.md b/README.md index 1273090ee6..39606579cb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ # Futbol Starter repository for the [Turing School](https://turing.io/) Futbol project. + +# Group Commitments and DTR +- As a group, we will check in regularly as we work on branches and move through iterations. Every merge will have a group checkin. + + +- We will move through the iterations and divy up assignments. Each member will create branches as they work on their assignment. We will most likely also have testing branches, in addition to the code branches. All merges will be looked at by the group and we will pr merge and update our local mains together. + +- A blend of async work and driver/navigator as needed when we run into problems or come together for merges. We will also look at using Trello. + +- We will try to be as DRY as possible. Refactoring is built-in to iteration 3, but we will try to maek our code as single responsible as possible as we work through. + +# Include link to your initial DTR document and the date it was completed. If you do additional DTRs later in the project, you should link the revised versions here as well with the date. New versions should be listed alongside older versions. Do not delete old DTRs. +https://docs.google.com/document/d/1NUJcmA-vbEgt1MOEZ9AMtp8D0DJWoKYct48TbbfzKg4/edit + +# Contributors +## Xander Hendry, Joseph Lee, Nathan Trautenberg +### LinkedIn accounts:https://www.linkedin.com/in/xander-hendry-70b804289/, https://www.linkedin.com/in/joseph-lee702/, https://www.linkedin.com/in/nathan-trautenberg-9106271a7/ +### Github links: https://github.com/XanderHendry, https://github.com/josephlee702, https://github.com/WagglyDessert diff --git a/data/test_game_teams.csv b/data/test_game_teams.csv new file mode 100644 index 0000000000..d9cb10abbb --- /dev/null +++ b/data/test_game_teams.csv @@ -0,0 +1,101 @@ +game_id,team_id,HoA,result,settled_in,head_coach,goals,shots,tackles,pim,powerPlayOpportunities,powerPlayGoals,faceOffWinPercentage,giveaways,takeaways +2012030221,3,away,LOSS,OT,John Tortorella,2,8,44,8,3,0,44.8,17,7 +2012030221,6,home,WIN,OT,Claude Julien,3,12,51,6,4,1,55.2,4,5 +2012030222,3,away,LOSS,REG,John Tortorella,2,9,33,11,5,0,51.7,1,4 +2012030222,6,home,WIN,REG,Claude Julien,3,8,36,19,1,0,48.3,16,6 +2012030223,6,away,WIN,REG,Claude Julien,2,8,28,6,0,0,61.8,10,7 +2012030223,3,home,LOSS,REG,John Tortorella,1,6,37,2,2,0,38.2,7,9 +2012030224,6,away,WIN,OT,Claude Julien,3,10,24,8,4,2,53.7,8,6 +2012030225,6,home,WIN,REG,Claude Julien,3,8,35,11,3,1,49.1,12,9 +2012030311,6,away,WIN,REG,Claude Julien,3,7,19,17,4,0,66.7,1,5 +2012030311,5,home,LOSS,REG,Dan Bylsma,0,7,34,28,4,0,33.3,8,9 +2012030312,6,away,WIN,REG,Claude Julien,4,7,19,6,1,0,50.9,2,5 +2012030312,5,home,LOSS,REG,Dan Bylsma,1,6,37,4,2,0,49.1,12,5 +2012030313,5,away,LOSS,OT,Dan Bylsma,1,13,46,16,6,0,57.3,8,10 +2012030313,6,home,WIN,OT,Claude Julien,2,10,34,18,5,0,42.7,10,13 +2012030314,5,away,LOSS,REG,Dan Bylsma,0,6,33,8,3,0,47.5,8,1 +2012030314,6,home,WIN,REG,Claude Julien,1,6,25,8,3,0,52.5,11,5 +2012030231,17,away,LOSS,REG,Mike Babcock,1,5,43,10,3,0,52.5,6,4 +2012030231,16,home,WIN,REG,Joel Quenneville,2,10,24,10,3,1,47.5,2,11 +2012030232,17,away,WIN,REG,Mike Babcock,2,7,26,6,4,0,55.4,6,6 +2012030232,16,home,LOSS,REG,Joel Quenneville,1,5,36,10,2,0,44.6,7,9 +2012030233,16,away,LOSS,REG,Joel Quenneville,1,10,22,22,4,0,43.9,5,6 +2012030233,17,home,WIN,REG,Mike Babcock,3,7,28,10,5,0,56.1,9,3 +2012030234,16,away,LOSS,REG,Joel Quenneville,0,7,22,10,3,0,48.3,8,4 +2012030234,17,home,WIN,REG,Mike Babcock,2,6,30,10,3,1,51.7,10,8 +2012030235,17,away,LOSS,REG,Mike Babcock,1,6,25,10,4,0,50.8,5,3 +2012030235,16,home,WIN,REG,Joel Quenneville,2,11,22,12,3,2,49.2,7,7 +2012030236,16,away,LOSS,REG,Joel Quenneville,2,7,16,10,5,1,39,3,5 +2012030236,17,home,WIN,REG,Mike Babcock,3,9,29,12,3,0,61,12,4 +2012030237,17,away,LOSS,OT,Mike Babcock,1,6,38,10,2,0,52.5,6,6 +2012030237,16,home,WIN,OT,Joel Quenneville,2,8,36,6,4,0,47.5,14,9 +2012030121,9,away,TIE,REG,Paul MacLean,2,7,31,23,2,0,39.4,9,1 +2012030121,8,home,TIE,REG,Michel Therrien,2,12,24,6,5,1,60.6,11,10 +2012030122,9,away,LOSS,REG,Paul MacLean,1,7,26,8,4,0,42.1,4,0 +2012030122,8,home,WIN,REG,Michel Therrien,3,8,37,12,2,0,57.9,7,6 +2012030123,8,away,LOSS,REG,Michel Therrien,1,8,44,129,6,1,47.7,13,8 +2012030123,9,home,WIN,REG,Paul MacLean,4,7,47,107,11,3,52.3,8,6 +2012030124,8,away,LOSS,OT,Michel Therrien,2,7,46,6,1,0,44.3,6,3 +2012030124,9,home,WIN,OT,Paul MacLean,3,8,61,2,3,0,55.7,12,5 +2012030125,9,away,WIN,REG,Paul MacLean,4,7,16,22,5,3,50.7,14,3 +2012030125,8,home,LOSS,REG,Michel Therrien,1,8,22,32,5,1,49.3,10,4 +2012030151,30,away,LOSS,OT,Mike Yeo,1,6,36,6,4,0,50,9,10 +2012030151,16,home,WIN,OT,Joel Quenneville,2,9,40,8,3,1,50,17,14 +2012030152,30,away,LOSS,REG,Mike Yeo,2,7,43,10,2,0,45.6,3,4 +2012030152,16,home,WIN,REG,Joel Quenneville,3,12,35,6,4,0,54.4,6,14 +2012030153,16,away,LOSS,OT,Joel Quenneville,2,6,13,8,2,0,44.4,3,2 +2012030153,30,home,WIN,OT,Mike Yeo,3,9,34,6,3,0,55.6,7,9 +2012030154,16,away,WIN,REG,Joel Quenneville,3,6,10,12,2,0,53.7,4,5 +2012030154,30,home,LOSS,REG,Mike Yeo,0,6,20,4,6,0,46.3,14,4 +2012030155,30,away,LOSS,REG,Mike Yeo,1,5,32,18,2,0,52.5,6,4 +2012030155,16,home,WIN,REG,Joel Quenneville,3,8,23,6,2,1,47.5,9,12 +2012030181,26,away,LOSS,OT,Darryl Sutter,1,7,41,12,2,0,36.2,6,6 +2012030181,19,home,WIN,OT,Ken Hitchcock,2,10,38,8,5,1,63.8,10,5 +2012030182,26,away,LOSS,REG,Darryl Sutter,1,7,38,8,4,1,44.8,2,6 +2012030182,19,home,WIN,REG,Ken Hitchcock,2,6,38,8,4,0,55.2,2,11 +2012030183,19,away,LOSS,REG,Ken Hitchcock,0,7,39,10,4,0,50.9,13,2 +2012030183,26,home,WIN,REG,Darryl Sutter,1,5,53,10,4,0,49.1,17,9 +2012030184,19,away,WIN,REG,Ken Hitchcock,3,5,46,8,2,1,48.3,12,5 +2012030184,26,home,LOSS,REG,Darryl Sutter,2,7,42,8,2,0,51.7,8,7 +2012030185,26,away,WIN,OT,Darryl Sutter,3,6,30,2,2,1,50,2,7 +2012030185,19,home,LOSS,OT,Ken Hitchcock,2,9,41,4,1,0,50,7,7 +2012030186,19,away,LOSS,REG,Ken Hitchcock,1,5,36,2,1,0,47.2,7,2 +2012030186,26,home,WIN,REG,Darryl Sutter,2,4,37,2,1,0,52.8,21,7 +2012030161,17,away,LOSS,REG,Mike Babcock,1,5,24,8,4,1,51.8,13,3 +2012030161,24,home,WIN,REG,Bruce Boudreau,3,6,35,8,4,2,48.2,8,2 +2012030162,17,away,WIN,OT,Mike Babcock,3,8,22,10,6,3,61.5,5,4 +2012030162,24,home,LOSS,OT,Bruce Boudreau,2,8,37,12,5,1,38.5,11,3 +2012030163,24,away,WIN,REG,Bruce Boudreau,2,7,26,14,6,2,49.2,3,5 +2012030163,17,home,LOSS,REG,Mike Babcock,0,5,16,25,6,0,50.8,9,5 +2012030164,24,away,LOSS,OT,Bruce Boudreau,2,8,26,2,3,0,55.7,3,5 +2012030164,17,home,WIN,OT,Mike Babcock,3,12,38,6,1,0,44.3,11,5 +2012030165,17,away,LOSS,OT,Mike Babcock,2,7,19,8,3,1,51.5,12,6 +2012030165,24,home,WIN,OT,Bruce Boudreau,3,8,32,11,3,1,48.5,15,5 +2012030166,24,away,WIN,OT,Bruce Boudreau,3,9,25,6,0,0,46.9,4,2 +2012030166,17,home,LOSS,OT,Mike Babcock,2,7,24,0,3,1,53.1,12,4 +2012030167,17,away,WIN,REG,Mike Babcock,3,8,18,10,2,0,50.6,5,9 +2012030167,24,home,LOSS,REG,Bruce Boudreau,2,8,34,6,4,1,49.4,9,4 +2012030111,2,away,LOSS,REG,Jack Capuano,0,6,41,51,4,0,51.6,4,3 +2012030111,5,home,WIN,REG,Dan Bylsma,3,6,36,38,4,2,48.4,2,7 +2012030112,2,away,LOSS,REG,Jack Capuano,2,10,31,15,4,1,39,2,4 +2012030112,5,home,WIN,REG,Dan Bylsma,3,8,28,15,4,1,61,11,4 +2012030113,5,away,WIN,OT,Dan Bylsma,3,6,33,8,5,3,47.5,8,6 +2012030113,2,home,LOSS,OT,Jack Capuano,2,9,35,12,3,0,52.5,14,19 +2012030114,5,away,LOSS,REG,Dan Bylsma,2,7,26,15,2,0,46.3,12,10 +2012030114,2,home,WIN,REG,Jack Capuano,4,6,33,11,4,1,53.7,8,13 +2012030115,2,away,LOSS,REG,Jack Capuano,0,7,27,36,2,0,36.2,2,4 +2012030115,5,home,WIN,REG,Dan Bylsma,2,7,33,30,5,1,63.8,8,5 +2012030116,5,away,LOSS,OT,Dan Bylsma,2,5,23,6,1,0,39.7,10,6 +2012030116,2,home,WIN,OT,Jack Capuano,3,9,31,2,3,0,60.3,7,15 +2012030131,3,away,LOSS,REG,John Tortorella,1,9,41,12,4,0,48.4,7,9 +2012030131,15,home,WIN,REG,Adam Oates,3,7,32,10,5,1,51.6,11,6 +2012030132,3,away,LOSS,OT,John Tortorella,0,6,58,8,3,0,48.6,7,5 +2012030132,15,home,WIN,OT,Adam Oates,1,9,50,10,2,1,51.4,8,11 +2012030133,15,away,WIN,REG,Adam Oates,3,7,22,12,3,0,52.6,6,4 +2012030133,3,home,LOSS,REG,John Tortorella,2,7,33,6,6,1,47.4,13,11 +2012030134,15,away,WIN,REG,Adam Oates,3,7,20,8,2,0,35.8,9,2 +2012030134,3,home,LOSS,REG,John Tortorella,2,8,38,4,4,1,64.2,4,8 +2012030135,3,away,LOSS,OT,John Tortorella,1,6,43,4,4,0,41.7,14,9 +2012030135,15,home,WIN,OT,Adam Oates,2,8,53,8,2,1,58.3,13,13 +2012030136,15,away,LOSS,REG,Adam Oates,0,6,28,14,0,0,40,5,3 +2012030136,3,home,WIN,REG,John Tortorella,1,7,33,4,5,0,60,7,6 \ No newline at end of file diff --git a/data/test_games.csv b/data/test_games.csv new file mode 100644 index 0000000000..cd0becb890 --- /dev/null +++ b/data/test_games.csv @@ -0,0 +1,74 @@ +game_id,season,type,date_time,away_team_id,home_team_id,away_goals,home_goals,venue,venue_link +2012030221,20122013,Postseason,5/16/13,3,6,2,3,Toyota Stadium,/api/v1/venues/null +2012030222,20122013,Postseason,5/19/13,3,6,2,3,Toyota Stadium,/api/v1/venues/null +2012030223,20122013,Postseason,5/21/13,6,3,2,1,BBVA Stadium,/api/v1/venues/null +2012030224,20122013,Postseason,5/23/13,6,3,3,2,BBVA Stadium,/api/v1/venues/null +2012030225,20122013,Postseason,5/25/13,3,6,1,3,Toyota Stadium,/api/v1/venues/null +2012030311,20122013,Postseason,6/2/13,6,5,3,0,Children's Mercy Park,/api/v1/venues/null +2012030312,20122013,Postseason,6/4/13,6,5,4,1,Children's Mercy Park,/api/v1/venues/null +2012030313,20122013,Postseason,6/6/13,5,6,1,2,Toyota Stadium,/api/v1/venues/null +2012030314,20122013,Postseason,6/8/13,5,6,0,1,Toyota Stadium,/api/v1/venues/null +2012030231,20122013,Postseason,5/16/13,17,16,1,2,Gillette Stadium,/api/v1/venues/null +2012030232,20122013,Postseason,5/18/13,17,16,2,1,Gillette Stadium,/api/v1/venues/null +2012030233,20122013,Postseason,5/20/13,16,17,1,3,Dignity Health Sports Park,/api/v1/venues/null +2012030234,20122013,Postseason,5/24/13,16,17,0,2,Dignity Health Sports Park,/api/v1/venues/null +2012030235,20122013,Postseason,5/26/13,17,16,1,2,Gillette Stadium,/api/v1/venues/null +2012030236,20122013,Postseason,5/28/13,16,17,2,3,Dignity Health Sports Park,/api/v1/venues/null +2012030237,20122013,Postseason,5/30/13,17,16,1,2,Gillette Stadium,/api/v1/venues/null +2012030121,20122013,Postseason,5/2/13,9,8,2,2,Red Bull Arena,/api/v1/venues/null +2012030122,20122013,Postseason,5/3/13,9,8,1,3,Red Bull Arena,/api/v1/venues/null +2012030123,20122013,Postseason,5/5/13,8,9,1,4,Yankee Stadium,/api/v1/venues/null +2012030124,20122013,Postseason,5/7/13,8,9,2,3,Yankee Stadium,/api/v1/venues/null +2012030125,20122013,Postseason,5/9/13,9,8,4,1,Red Bull Arena,/api/v1/venues/null +2012030151,20122013,Postseason,5/1/13,30,16,1,2,Gillette Stadium,/api/v1/venues/null +2012030152,20122013,Postseason,5/4/13,30,16,2,3,Gillette Stadium,/api/v1/venues/null +2012030153,20122013,Postseason,5/5/13,16,30,2,3,Exploria Stadium,/api/v1/venues/null +2012030154,20122013,Postseason,5/8/13,16,30,3,0,Exploria Stadium,/api/v1/venues/null +2012030155,20122013,Postseason,5/10/13,30,16,1,3,Gillette Stadium,/api/v1/venues/null +2012030181,20122013,Postseason,5/1/13,26,19,1,2,Talen Energy Stadium,/api/v1/venues/null +2012030182,20122013,Postseason,5/3/13,26,19,1,2,Talen Energy Stadium,/api/v1/venues/null +2012030183,20122013,Postseason,5/5/13,19,26,0,1,Nippert Stadium,/api/v1/venues/null +2012030184,20122013,Postseason,5/7/13,19,26,3,2,Nippert Stadium,/api/v1/venues/null +2012030185,20122013,Postseason,5/9/13,26,19,3,2,Talen Energy Stadium,/api/v1/venues/null +2012030186,20122013,Postseason,5/11/13,19,26,1,2,Nippert Stadium,/api/v1/venues/null +2012030161,20122013,Postseason,5/1/13,17,24,1,3,Rio Tinto Stadium,/api/v1/venues/null +2012030162,20122013,Postseason,5/3/13,17,24,3,2,Rio Tinto Stadium,/api/v1/venues/null +2012030163,20122013,Postseason,5/4/13,24,17,2,0,Dignity Health Sports Park,/api/v1/venues/null +2012030164,20122013,Postseason,5/7/13,24,17,2,3,Dignity Health Sports Park,/api/v1/venues/null +2012030165,20122013,Postseason,5/9/13,17,24,2,3,Rio Tinto Stadium,/api/v1/venues/null +2012030166,20122013,Postseason,5/11/13,24,17,3,2,Dignity Health Sports Park,/api/v1/venues/null +2012030167,20122013,Postseason,5/13/13,17,24,3,2,Rio Tinto Stadium,/api/v1/venues/null +2012030111,20122013,Postseason,5/1/13,2,5,0,3,Children's Mercy Park,/api/v1/venues/null +2012030112,20122013,Postseason,5/3/13,2,5,2,3,Children's Mercy Park,/api/v1/venues/null +2012030113,20122013,Postseason,5/5/13,5,2,3,2,Centruy Link Field,/api/v1/venues/null +2012030114,20122013,Postseason,5/7/13,5,2,2,4,Centruy Link Field,/api/v1/venues/null +2012030115,20122013,Postseason,5/9/13,2,5,0,2,Children's Mercy Park,/api/v1/venues/null +2012030116,20122013,Postseason,5/11/13,5,2,2,3,Centruy Link Field,/api/v1/venues/null +2012030131,20122013,Postseason,5/2/13,3,15,1,3,Providence Park,/api/v1/venues/null +2012030132,20122013,Postseason,5/4/13,3,15,0,1,Providence Park,/api/v1/venues/null +2012030133,20122013,Postseason,5/6/13,15,3,3,2,BBVA Stadium,/api/v1/venues/null +2012030134,20122013,Postseason,5/8/13,15,3,3,2,BBVA Stadium,/api/v1/venues/null +2012030135,20122013,Postseason,5/10/13,3,15,1,2,Providence Park,/api/v1/venues/null +2012030136,20122013,Postseason,5/12/13,15,3,0,1,BBVA Stadium,/api/v1/venues/null +2012030137,20122013,Postseason,5/14/13,3,15,3,0,Providence Park,/api/v1/venues/null +2012030321,20122013,Postseason,6/1/13,26,16,1,2,Gillette Stadium,/api/v1/venues/null +2012030322,20122013,Postseason,6/3/13,26,16,2,2,Gillette Stadium,/api/v1/venues/null +2012030323,20122013,Postseason,6/5/13,16,26,1,3,Nippert Stadium,/api/v1/venues/null +2012030324,20122013,Postseason,6/7/13,16,26,3,2,Nippert Stadium,/api/v1/venues/null +2012030325,20122013,Postseason,6/9/13,26,16,3,2,Gillette Stadium,/api/v1/venues/null +2016030171,20162017,Postseason,4/14/17,20,24,2,3,Rio Tinto Stadium,/api/v1/venues/null +2016030172,20162017,Postseason,4/16/17,20,24,2,3,Rio Tinto Stadium,/api/v1/venues/null +2016030173,20162017,Postseason,4/18/17,24,20,3,2,BMO Field,/api/v1/venues/null +2016030174,20162017,Postseason,4/20/17,24,20,3,1,BMO Field,/api/v1/venues/null +2014030411,20142015,Postseason,6/4/15,16,14,2,1,Audi Field,/api/v1/venues/null +2014030412,20142015,Postseason,6/6/15,16,14,3,2,Audi Field,/api/v1/venues/null +2014030413,20142015,Postseason,6/9/15,14,16,3,2,Gillette Stadium,/api/v1/venues/null +2014030414,20142015,Postseason,6/11/15,14,16,1,2,Gillette Stadium,/api/v1/venues/null +2014030415,20142015,Postseason,6/14/15,16,14,2,1,Audi Field,/api/v1/venues/null +2014030416,20142015,Postseason,6/16/15,14,16,0,2,Gillette Stadium,/api/v1/venues/null +2015030141,20152016,Postseason,4/14/16,3,5,2,3,Children's Mercy Park,/api/v1/venues/null +2015030142,20152016,Postseason,4/16/16,3,5,2,2,Children's Mercy Park,/api/v1/venues/null +2015030143,20152016,Postseason,4/19/16,5,3,3,1,BBVA Stadium,/api/v1/venues/null +2015030144,20152016,Postseason,4/21/16,5,3,3,0,BBVA Stadium,/api/v1/venues/null +2015030145,20152016,Postseason,4/23/16,3,5,3,4,Children's Mercy Park,/api/v1/venues/null +2015030181,20152016,Postseason,4/15/16,28,26,2,3,Nippert Stadium,/api/v1/venues/null \ No newline at end of file diff --git a/lib/game.rb b/lib/game.rb new file mode 100644 index 0000000000..2fdc366fdc --- /dev/null +++ b/lib/game.rb @@ -0,0 +1,25 @@ +class Game + attr_reader :game_id, + :season, + :type, + :date_time, + :away_team_id, + :home_team_id, + :away_goals, + :home_goals, + :venue, + :venue_link + + def initialize(game_info) + @game_id = game_info[:game_id].to_i + @season = game_info[:season].to_i + @type = game_info[:type] + @date_time = game_info[:date_time] + @away_team_id = game_info[:away_team_id].to_i + @home_team_id = game_info[:home_team_id].to_i + @away_goals = game_info[:away_goals].to_i + @home_goals = game_info[:home_goals].to_i + @venue = game_info[:venue] + @venue_link = game_info[:venue_link] + end +end \ No newline at end of file diff --git a/lib/game_teams.rb b/lib/game_teams.rb new file mode 100644 index 0000000000..74ee687668 --- /dev/null +++ b/lib/game_teams.rb @@ -0,0 +1,34 @@ +class GameTeam + attr_reader :game_id, + :team_id, + :hoa, + :result, + :settled_in, + :head_coach, + :goals, + :shots, + :tackles, + :pim, + :power_play_opportunities, + :power_play_goals, + :faceoff_win_percentage, + :giveaways, + :takeaways + def initialize(game_team_info) + @game_id = game_team_info[:game_id].to_i + @team_id = game_team_info[:team_id].to_i + @hoa = game_team_info[:hoa] + @result = game_team_info[:result] + @settled_in = game_team_info[:settled_in] + @head_coach = game_team_info[:head_coach] + @goals = game_team_info[:goals].to_i + @shots = game_team_info[:shots].to_i + @tackles = game_team_info[:tackles].to_i + @pim = game_team_info[:pim].to_i + @power_play_opportunities = game_team_info[:powerplayopportunities].to_i + @power_play_goals = game_team_info[:powerplaygoals].to_i + @faceoff_win_percentage = game_team_info[:faceoffwinpercentage].to_f + @giveaways = game_team_info[:giveaways].to_i + @takeaways = game_team_info[:takeaways].to_i + end +end \ No newline at end of file diff --git a/lib/stat_tracker.rb b/lib/stat_tracker.rb new file mode 100644 index 0000000000..854d987a75 --- /dev/null +++ b/lib/stat_tracker.rb @@ -0,0 +1,327 @@ +require "csv" +class StatTracker + attr_reader :teams, + :games, + :game_teams + + def initialize(content) + @teams = content[:teams] + @games = content[:games] + @game_teams = content[:game_teams] + end + + def self.from_csv(locations) + # convert each CSV into an array of associated instance objects, ie. teams_arry holds an array of Team objects + teams_arry = CSV.readlines(locations[:teams], headers: true, header_converters: :symbol).map { |team| Team.new(team) } + games_arry = CSV.readlines(locations[:games], headers: true, header_converters: :symbol).map { |game| Game.new(game) } + game_teams_arry = CSV.readlines(locations[:game_teams], headers: true, header_converters: :symbol).map { |game_team| GameTeam.new(game_team)} + # combine all arrays to be stored in a Hash so we can easily call each array + contents = { + teams: teams_arry, + games: games_arry, + game_teams: game_teams_arry + } + # pass contents hash on to StatTracker to initiate the class. + StatTracker.new(contents) + end + +# Game Statistic Method + def highest_total_score + max = @games.map {|game| game.home_goals + game.away_goals }.max + end + + def lowest_total_score + min = @games.map {|game| game.home_goals + game.away_goals }.min + end + + def percentage_home_wins + hash = Hash.new{ |hash, key| hash[key] = [] } + total_games = 0 + @game_teams.each do |game| + total_games += 0.50 + key = game.game_id + value_array = [] + value1 = game.result + value2 = game.hoa + value_array << value1 + value_array << value2 + hash[key] = value_array + end + home_win = 0.00 + hash.values.each do |hashy| + if hashy[0] == "WIN" && hashy[1] == "home" + home_win += 1.00 + end + end + x = home_win / total_games + (x * 100).round(2) + end + + def percentage_visitor_wins + hash = Hash.new{ |hash, key| hash[key] = [] } + total_games = 0 + @game_teams.each do |game| + total_games += 0.50 + key = game.game_id + value_array = [] + value1 = game.result + value2 = game.hoa + value_array << value1 + value_array << value2 + hash[key] = value_array + end + visitor_win = 0.00 + hash.values.each do |hashy| + if hashy[0] == "LOSS" && hashy[1] == "home" + visitor_win += 1.00 + end + end + x = visitor_win / total_games + (x * 100).round(2) + end + + def percentage_ties + hash = Hash.new{ |hash, key| hash[key] = [] } + total_games = 0 + @game_teams.each do |game| + total_games += 0.50 + key = game.game_id + value_array = [] + value1 = game.result + value2 = game.hoa + value_array << value1 + value_array << value2 + hash[key] = value_array + end + tie = 0.00 + hash.values.each do |hashy| + if hashy[0] == "TIE" && hashy[1] == "home" + tie += 1.00 + end + end + x = tie / total_games + (x * 100).round(2) + end + + + def count_of_games_by_season + games_per_season = Hash.new(0) + @games.each do |game| + games_per_season[game.season] += 1 + end + games_per_season + end + + + def average_goals_per_game + @home_goals = 0.0 + @away_goals = 0.0 + @games.each do |game| + @home_goals += game.home_goals + @away_goals += game.away_goals + end + total_goals = @home_goals+@away_goals + number_of_games = @games.count + @average_goals = (total_goals/number_of_games) + @average_goals.round(2) + end + + def average_goals_by_season + hash = Hash.new{ |hash, key| hash[key] = 0.00 } + total_goals = 0.00 + total_games = 0.00 + @games.each do |game| + key = game.season + value1 = game.away_goals + value2 = game.home_goals + total_games += 1.00 + total_goals += value1 + total_goals += value2 + avg_goals_game = (total_goals / total_games) + hash[key] = avg_goals_game.round(2) + end + hash + end + +# League Statistic Methods + def count_of_teams + @teams.count + end + + def best_offense + teams_goals_average = {} + @teams.each do |team| + total_games = 0 + total_goals = 0 + games = @game_teams.each do |game_team| + if game_team.team_id == team.team_id + total_games +=1 + total_goals += game_team.goals + end + end + if total_games > 0 && total_goals > 0 + teams_goals_average["#{team.name}"] = (total_goals.to_f / total_games.to_f) + end + end + best_offense = teams_goals_average.find { |team, avg| avg == teams_goals_average.values.max} + best_offense.first + end + + def worst_offense + teams_goals_average = {} + @teams.each do |team| + total_games = 0 + total_goals = 0 + games = @game_teams.each do |game_team| + if game_team.team_id == team.team_id + total_games +=1 + total_goals += game_team.goals + end + end + if total_games > 0 && total_goals + teams_goals_average["#{team.name}"] = (total_goals.to_f / total_games.to_f) + end + end + worst_offense = teams_goals_average.find { |team, avg| avg == teams_goals_average.values.min} + worst_offense.first + end + +#Season Statistic Methods + def winningest_coach(season) + #number of wins for each coach + coach_wins = Hash.new(0) + #opportunity here to create a helper method (to find all games in a season) and just call that + season_games = @games.find_all { |game| game.season == season } + season_games = season_games.map do |game| + game.game_id + end + @game_teams.each do |game_team| + if game_team.result == "WIN" && season_games.include?(game_team.game_id) + coach_wins[game_team.head_coach] += 1 + end + end + #number of games played by each coach's team + coach_total_games = Hash.new(0) + @game_teams.each do |game_team| + if season_games.include?(game_team.game_id) + coach_total_games[game_team.head_coach] += 1 + end + end + #now we divide each coach's wins by the number of games their team played + coach_win_percentage = {} + coach_wins.each do |coach, wins| + coach_win_percentage[coach] = (wins.to_f/coach_total_games[coach].to_f) + end + winningest_coach = coach_win_percentage.find{ |key, value| value == coach_win_percentage.values.max } + winningest_coach.first + end + + def worst_coach(season) + coach_losses = Hash.new(0) + season_games = @games.find_all { |game| game.season == season } + season_games = season_games.map do |game| + game.game_id + end + @game_teams.each do |game_team| + if game_team.result == "LOSS" && season_games.include?(game_team.game_id) + coach_losses[game_team.head_coach] += 1 + end + end + #number of games played by each coach's team + coach_total_games = Hash.new(0) + @game_teams.each { |game_team| coach_total_games[game_team.head_coach] += 1 } + #now we divide each coach's wins by the number of games their team played + coach_loss_percentage = {} + coach_losses.each { |coach, losses| coach_loss_percentage[coach] = (losses.to_f/coach_total_games[coach].to_f) } + worst_coach = coach_loss_percentage.find{ |key, value| value == coach_loss_percentage.values.max } + worst_coach.first + end + + def most_accurate_team(season) + accuracy_by_team = {} + #sets team names to keys + @teams.each do |team| + season_games = @games.find_all { |game| game.season == season } + season_games = season_games.map do |game| + game.game_id + end + goals = 0 + shots = 0 + @game_teams.each do |game_team| + if season_games.include?(game_team.game_id) && game_team.team_id == team.team_id + goals += game_team.goals + shots += game_team.shots + end + end + if goals > 0 && shots > 0 + accuracy_by_team[team.name] = goals.to_f/shots.to_f + end + end + accuracy_by_team.max.first + #goals / shots is what we need + end + + def least_accurate_team(season) + accuracy_by_team = {} + #sets team names to keys + @teams.each do |team| + season_games = @games.find_all { |game| game.season == season } + season_games = season_games.map do |game| + game.game_id + end + goals = 0 + shots = 0 + @game_teams.each do |game_team| + if season_games.include?(game_team.game_id) && game_team.team_id == team.team_id + goals += game_team.goals + shots += game_team.shots + end + end + if goals > 0 && shots > 0 + accuracy_by_team[team.name] = goals.to_f/shots.to_f + end + end + accuracy_by_team.min.first + #goals / shots is what we need + end + + def most_tackles(season) + tackles_by_team = {} + @teams.each do |team| + season_games = @games.find_all { |game| game.season == season} + season_games = season_games.map do |game| + game.game_id + end + tackles = 0 + @game_teams.each do |game_team| + if season_games.include?(game_team.game_id) && game_team.team_id == team.team_id + tackles += game_team.tackles + end + end + if tackles > 0 + tackles_by_team[team.name] = tackles + end + end + tackles_by_team.max.first + end + + def fewest_tackles(season) + tackles_by_team = {} + @teams.each do |team| + season_games = @games.find_all { |game| game.season == season} + season_games = season_games.map do |game| + game.game_id + end + tackles = 0 + @game_teams.each do |game_team| + if season_games.include?(game_team.game_id) && game_team.team_id == team.team_id + tackles += game_team.tackles + end + end + if tackles > 0 + tackles_by_team[team.name] = tackles + end + end + tackles_by_team.min.first + end +end diff --git a/lib/team.rb b/lib/team.rb new file mode 100644 index 0000000000..9b0a679f21 --- /dev/null +++ b/lib/team.rb @@ -0,0 +1,16 @@ +class Team + attr_reader :team_id, + :franchise_id, + :name, + :abbreviation, + :stadium, + :link + def initialize(team_info) + @team_id = team_info[:team_id].to_i + @franchise_id = team_info[:franchiseid].to_i + @name = team_info[:teamname] + @abbreviation = team_info[:abbreviation] + @stadium = team_info[:stadium] + @link = team_info[:link] + end +end \ No newline at end of file diff --git a/runner.rb b/runner.rb new file mode 100644 index 0000000000..b89a8638ec --- /dev/null +++ b/runner.rb @@ -0,0 +1,20 @@ +# runner.rb +require './spec/spec_helper' + +# game_path = './data/games.csv' +# team_path = './data/teams.csv' +# game_teams_path = './data/game_teams.csv' + +game_path = './data/test_games.csv' +team_path = './data/teams.csv' +game_teams_path = './data/test_game_teams.csv' + +locations = { + games: game_path, + teams: team_path, + game_teams: game_teams_path +} + +stat_tracker = StatTracker.from_csv(locations) + +require 'pry'; binding.pry \ No newline at end of file diff --git a/spec/game_spec.rb b/spec/game_spec.rb new file mode 100644 index 0000000000..6fdcad3603 --- /dev/null +++ b/spec/game_spec.rb @@ -0,0 +1,22 @@ +require './spec/spec_helper' + +RSpec.describe Game do + let(:game_data) { CSV.readlines('./data/test_games.csv', headers: true, header_converters: :symbol) } + let(:game) { Game.new(game_data.first) } + + describe '#initialize' do + it 'exists' do + expect(game).to be_a(Game) + expect(game.game_id).to eq(2012030221) + expect(game.season).to eq(20122013) + expect(game.type).to eq('Postseason') + expect(game.date_time).to eq('5/16/13') + expect(game.away_team_id).to eq(3) + expect(game.home_team_id).to eq(6) + expect(game.away_goals).to eq(2) + expect(game.home_goals).to eq(3) + expect(game.venue).to eq('Toyota Stadium') + expect(game.venue_link).to eq('/api/v1/venues/null') + end + end +end \ No newline at end of file diff --git a/spec/game_teams_spec.rb b/spec/game_teams_spec.rb new file mode 100644 index 0000000000..0e5143a90c --- /dev/null +++ b/spec/game_teams_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +RSpec.describe GameTeam do + let(:game_teams_data) { CSV.readlines('./data/test_game_teams.csv', headers: true, header_converters: :symbol) } + let(:game_team) { GameTeam.new(game_teams_data.first) } + + describe '#initialize' do + it 'exists' do + expect(game_team).to be_a(GameTeam) + expect(game_team.game_id).to eq(2012030221) + expect(game_team.team_id).to eq(3) + expect(game_team.hoa).to eq("away") + expect(game_team.result).to eq("LOSS") + expect(game_team.settled_in).to eq("OT") + expect(game_team.head_coach).to eq("John Tortorella") + expect(game_team.goals).to eq(2) + expect(game_team.shots).to eq(8) + expect(game_team.tackles).to eq(44) + expect(game_team.pim).to eq(8) + expect(game_team.power_play_opportunities).to eq(3) + expect(game_team.power_play_goals).to eq(0) + expect(game_team.faceoff_win_percentage).to eq(44.8) + expect(game_team.giveaways).to eq(17) + expect(game_team.takeaways).to eq(7) + end + end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000000..f61054d174 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,16 @@ +# require 'simplecov' +# SimpleCov.start +require './lib/stat_tracker' +require './lib/game' +require './lib/team' +require './lib/game_teams' + +game_path = './data/games.csv' +team_path = './data/teams.csv' +game_teams_path = './data/game_teams.csv' + +locations = { + games: game_path, + teams: team_path, + game_teams: game_teams_path +} \ No newline at end of file diff --git a/spec/stat_tracker_spec.rb b/spec/stat_tracker_spec.rb new file mode 100644 index 0000000000..89e2d37c23 --- /dev/null +++ b/spec/stat_tracker_spec.rb @@ -0,0 +1,168 @@ +require 'spec_helper' +RSpec.describe StatTracker do + let(:game_path) { './data/test_games.csv' } + let(:team_path) { './data/teams.csv' } + let(:game_teams_path) { './data/test_game_teams.csv' } + let(:test_locations) { + {games: game_path, + teams: team_path, + game_teams: game_teams_path} + } + let(:stat_tracker) { StatTracker.from_csv(test_locations) } + + describe "::from_csv" do + it 'will create a new instance of StatTracker using data from the given csv' do + expect(stat_tracker).to be_a(StatTracker) + end + it 'will create an array of Team objects to be used by the StatTracker' do + expect(stat_tracker.teams).to be_a(Array) + expect(stat_tracker.teams.first).to be_a(Team) + end + it 'will create an array of Game objects to be used by the StatTracker' do + expect(stat_tracker.games).to be_a(Array) + expect(stat_tracker.games.first).to be_a(Game) + end + it 'will create an array of GameTeam objects to be used by the StatTracker' do + expect(stat_tracker.game_teams).to be_a(Array) + expect(stat_tracker.game_teams.first).to be_a(GameTeam) + end + end + context 'Game Statistic Methods' do + describe "#highest total score" do + it 'will find the highest sum of the winning and losing teams scores and return them as integers' do + expect(stat_tracker.highest_total_score).to be_an(Integer) + expect(stat_tracker.highest_total_score).to eq(7) + end + end + describe "#lowest total score" do + it 'will find the lowest sum of the winning and losing teams scores' do + expect(stat_tracker.lowest_total_score).to be_an(Integer) + expect(stat_tracker.lowest_total_score).to eq(1) + end + end + describe "#percentage home wins" do + it 'will find the percentage of games that a home team has won' do + expect(stat_tracker.percentage_home_wins).to be_a(Float) + expect(stat_tracker.percentage_home_wins).to eq(68.0) + end + end + describe "#percentage visitor wins" do + it 'will find the percentage of games that a visitor has won' do + expect(stat_tracker.percentage_visitor_wins).to be_a(Float) + expect(stat_tracker.percentage_visitor_wins).to eq(30.0) + end + end + describe "#percentage_ties" do + it 'will find the percentage of games that ended in a tie' do + expect(stat_tracker.percentage_ties).to be_a(Float) + expect(stat_tracker.percentage_ties).to eq(2.00) + end + end + describe '#count_of_games_by_season' do + it 'will return a A hash with season names as keys and counts of games as values' do + expect(stat_tracker.count_of_games_by_season).to be_a(Hash) + expect(stat_tracker.count_of_games_by_season).to eq({20122013=>57, 20162017=>4, 20142015=>6, 20152016=>6}) + end + end + describe '#average_goals_per_game' do + it 'will return the average number of goals scored accross all seasons including both home and away goals' do + expect(stat_tracker.average_goals_per_game).to be_a(Float) + expect(stat_tracker.average_goals_per_game).to eq(3.95) + end + end + describe '#average_goals_by_season' do + it 'will return a hash with season names as keys, and a float representing the average number of goals in a game for that season as values' do + expect(stat_tracker.average_goals_by_season).to be_a(Hash) + expect(stat_tracker.average_goals_by_season).to eq({20122013=>3.86, 20162017=>3.92, 20142015=>3.88, 20152016=>3.95}) + end + end + end + context 'League Statistic Methods' do + xdescribe '#count_of_teams' do + it 'will return an integer with the total number of teams in the data' do + expect(stat_tracker.count_of_teams).to be_a(Integer) + expect(stat_tracker.count_of_teams).to eq(32) + end + end + describe '#best_offense' do + it 'will return a string with the name of the team with the highest average number of goals scored per game across all seasons' do + expect(stat_tracker.best_offense).to be_a(String) + expect(stat_tracker.best_offense).to eq("New York City FC") + end + end + describe '#worst_offense' do + it 'will return a string with the name of the team with the lowest average number of goals scored per game across all seasons' do + # expect(stat_tracker.worst_offense).to be_a(String) + expect(stat_tracker.worst_offense).to eq("Houston Dynamo") + end + end + xdescribe '#highest_scoring_visitor' do + it 'will return a string with the name of the team with the highest average score per game across all seasons when they are away' do + expect(stat_tracker.count_of_teams).to be_a(String) + expect(stat_tracker.count_of_teams).to eq() + end + end + xdescribe '#lowest_scoring_visitor' do + it 'will return a string with the name of the team with the lowest average score per game across all seasons when they are away' do + expect(stat_tracker.count_of_teams).to be_a(String) + expect(stat_tracker.count_of_teams).to eq() + end + end + xdescribe '#highest_scoring_home_team' do + it 'will return a string with the name of the team of the team with the highest average score per game across all seasons when they are home' do + expect(stat_tracker.count_of_teams).to be_a(String) + expect(stat_tracker.count_of_teams).to eq() + end + end + xdescribe '#lowest_scoring_home_team' do + it 'will return a string with the name of the team of the team with the lowest average score per game across all seasons when they are home' do + expect(stat_tracker.count_of_teams).to be_a(String) + expect(stat_tracker.count_of_teams).to eq() + end + end + end + + context 'Season Statistic Methods' do + describe "#winningest_coach" do + it 'will find the coach with the highest win percentage' do + expect(stat_tracker.winningest_coach(20122013)).to be_an(String) + expect(stat_tracker.winningest_coach(20122013)).to eq("Claude Julien") + end + end + + describe "#worst_coach" do + it 'will find the coach with the lowest win percentage' do + expect(stat_tracker.worst_coach(20122013)).to be_an(String) + expect(stat_tracker.worst_coach(20122013)).to eq("John Tortorella") + end + end + + describe "#most_accurate_team" do + it 'will find the team with best shots to goals ratio for the season' do + expect(stat_tracker.most_accurate_team(20122013)).to be_an(String) + expect(stat_tracker.most_accurate_team(20122013)).to eq("Sporting Kansas City") + end + end + + describe "#least_accurate_team" do + it 'will find the team with worst shots to goals ratio for the season' do + expect(stat_tracker.least_accurate_team(20122013)).to be_an(String) + expect(stat_tracker.least_accurate_team(20122013)).to eq("FC Cincinnati") + end + end + + describe "#most_tackles" do + it 'will find the team with the most tackles in the season' do + expect(stat_tracker.most_tackles(20122013)).to be_an(String) + expect(stat_tracker.most_tackles(20122013)).to eq("Sporting Kansas City") + end + end + + describe "#fewest_tackles" do + it 'will find the team with the fewest tackles in the season' do + expect(stat_tracker.fewest_tackles(20122013)).to be_an(String) + expect(stat_tracker.fewest_tackles(20122013)).to eq("FC Cincinnati") + end + end + end +end \ No newline at end of file diff --git a/spec/team_spec.rb b/spec/team_spec.rb new file mode 100644 index 0000000000..99f392f6e0 --- /dev/null +++ b/spec/team_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' +RSpec.describe Team do + let(:team_data) { CSV.readlines('./data/teams.csv', headers: true, header_converters: :symbol) } + let(:team) { Team.new(team_data.first) } + describe 'Initialize' do + it 'can initialize' do + expect(team).to be_a(Team) + expect(team.team_id).to eq(1) + expect(team.franchise_id).to eq(23) + expect(team.name).to eq("Atlanta United") + expect(team.abbreviation).to eq("ATL") + expect(team.stadium).to eq("Mercedes-Benz Stadium") + expect(team.link).to eq("/api/v1/teams/1") + end + end +end \ No newline at end of file