Last active
January 1, 2016 14:08
-
-
Save msmol/8155418 to your computer and use it in GitHub Desktop.
Some stats for my fantasy hockey pool. Check it out with nbviewer: http://nbviewer.ipython.org/gist/msmol/8155418
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "HaFHL Stats" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": "HaFHL Stats" | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": "Preamble" | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": "I recently made some statistics in Excel for my Fantasy Hockey Pool, the Hipster and Friends Hockey League (HaFHL). I started wondering what kind of effort would be involved to replicate what I had done in Python. You can find the results of this question below. You can find the original Excel version <a href=\"http://mitch.smolash.com/hafhl-stats.xlsx\">here</a> " | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": "Parsing the CSV Data" | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Let's first import the modules we're going to need to use plus define some handy lists we're going to need later on:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "import csv\nimport StringIO\nimport sys\n\nplayer_names = [\"Dwayne Gretskeet\", \"South Park Cows\", \"the favorites\", \n \"Pmoda\", \"Fresh Baked Brownies\", \"JoshHum\", \"Pika Pikachus\", \n \"BenDover\", \"Mikhail's Team\", \"First Place\", \"Team Leaddz\", \n \"EWeb FTW\", \"HERRO. THIS IS DOG\", \"Matthew's Team\"]\n\nscoring_categories = [\"G\", \"A\", \"+/-\", \"PIM\", \"PPP\", \"SOG\", \"W\", \"GAA\", \"SV%\", \"SHO\"]", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "And now do the actual parsing into some data structures:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "csv_data = \"\"\"Player,G,A,+/-,PIM,PPP,SOG,W,GAA,SV%,SHO\nDwayne Gretskeet,154,191,26,379,109,1325,38,2.32,0.926,4\nSouth Park Cows,141,191,46,282,115,1157,31,2.57,0.92,4\nMikhail's Team,138,160,40,268,97,1233,13,2.88,0.9,3\nthe favorites,132,153,82,307,76,1269,33,2.23,0.918,5\nPmoda,124,186,-25,318,97,1283,32,2.11,0.919,4\nJoshHum,121,198,-22,227,115,1263,21,2.93,0.914,2\nBenDover,119,206,74,248,88,1064,22,2.52,0.905,0\nPika Pikachus,113,201,59,177,103,1022,21,2.65,0.91,2\nFresh Baked Brownies,95,185,36,262,91,1092,25,2.01,0.926,5\nMatthew's Team,89,169,9,256,97,1052,13,3.11,0.898,1\nFirst Place,88,214,-51,186,108,932,29,2.64,0.909,2\nHERRO. THIS IS DOG,83,148,51,245,70,912,19,2.84,0.914,2\nEWeb FTW,81,149,-28,164,70,826,26,2.4,0.909,5\nTeam Leaddz,81,156,14,279,72,941,16,2.61,0.906,2\n\"\"\"\nf = StringIO.StringIO(csv_data)\nreader = csv.DictReader(f)\n\nper_player_stats = {i['Player']: {x: i[x] for x in scoring_categories} for i in reader}", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Awesome. Let's take a look at our data (it should look pretty similar to our original CSV) by defining a print function for our data structure:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "from IPython.core.display import HTML\n\ndef print_stats(stats, columns, keyword):\n output = '<table>'\n output += '<tr><th>' + keyword + '</th>'\n for col in columns:\n output += '<th>' + col + '</th>'\n output += \"</tr>\"\n \n for k,v in stats.iteritems():\n output += '<tr><td>' + k + '</td>'\n for col in columns:\n output += '<td>' + str(v[col]) + '</td>'\n output += '</tr>'\n output += \"</table>\"\n return HTML(output)\n \ndef print_players(players, columns):\n return print_stats(players, columns, \"Player\")\n \ndef print_categories(categories, columns):\n return print_stats(categories, columns, \"Category\")\n\nprint_players(per_player_stats, scoring_categories)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>G</th><th>A</th><th>+/-</th><th>PIM</th><th>PPP</th><th>SOG</th><th>W</th><th>GAA</th><th>SV%</th><th>SHO</th></tr><tr><td>Pmoda</td><td>124</td><td>186</td><td>-25</td><td>318</td><td>97</td><td>1283</td><td>32</td><td>2.11</td><td>0.919</td><td>4</td></tr><tr><td>Matthew's Team</td><td>89</td><td>169</td><td>9</td><td>256</td><td>97</td><td>1052</td><td>13</td><td>3.11</td><td>0.898</td><td>1</td></tr><tr><td>South Park Cows</td><td>141</td><td>191</td><td>46</td><td>282</td><td>115</td><td>1157</td><td>31</td><td>2.57</td><td>0.92</td><td>4</td></tr><tr><td>JoshHum</td><td>121</td><td>198</td><td>-22</td><td>227</td><td>115</td><td>1263</td><td>21</td><td>2.93</td><td>0.914</td><td>2</td></tr><tr><td>Dwayne Gretskeet</td><td>154</td><td>191</td><td>26</td><td>379</td><td>109</td><td>1325</td><td>38</td><td>2.32</td><td>0.926</td><td>4</td></tr><tr><td>Fresh Baked Brownies</td><td>95</td><td>185</td><td>36</td><td>262</td><td>91</td><td>1092</td><td>25</td><td>2.01</td><td>0.926</td><td>5</td></tr><tr><td>First Place</td><td>88</td><td>214</td><td>-51</td><td>186</td><td>108</td><td>932</td><td>29</td><td>2.64</td><td>0.909</td><td>2</td></tr><tr><td>Pika Pikachus</td><td>113</td><td>201</td><td>59</td><td>177</td><td>103</td><td>1022</td><td>21</td><td>2.65</td><td>0.91</td><td>2</td></tr><tr><td>the favorites</td><td>132</td><td>153</td><td>82</td><td>307</td><td>76</td><td>1269</td><td>33</td><td>2.23</td><td>0.918</td><td>5</td></tr><tr><td>Mikhail's Team</td><td>138</td><td>160</td><td>40</td><td>268</td><td>97</td><td>1233</td><td>13</td><td>2.88</td><td>0.9</td><td>3</td></tr><tr><td>BenDover</td><td>119</td><td>206</td><td>74</td><td>248</td><td>88</td><td>1064</td><td>22</td><td>2.52</td><td>0.905</td><td>0</td></tr><tr><td>Team Leaddz</td><td>81</td><td>156</td><td>14</td><td>279</td><td>72</td><td>941</td><td>16</td><td>2.61</td><td>0.906</td><td>2</td></tr><tr><td>HERRO. THIS IS DOG</td><td>83</td><td>148</td><td>51</td><td>245</td><td>70</td><td>912</td><td>19</td><td>2.84</td><td>0.914</td><td>2</td></tr><tr><td>EWeb FTW</td><td>81</td><td>149</td><td>-28</td><td>164</td><td>70</td><td>826</td><td>26</td><td>2.4</td><td>0.909</td><td>5</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 3, | |
"text": "<IPython.core.display.HTML at 0x328a090>" | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Nice!\n\nNow let's get into the real fun: ranking the data. What is a rank you ask? Well, let's take Goals as an example: \n\nThe person with the most Goals will have a ranking of 1, second most -- 2, etc. We're going to do this for each stat category.\n\nFirst, let's define a function to rank each category:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "def rank(unranked, reverse=True):\n ranked = {}\n for x in unranked:\n ranked_values = sorted(unranked.values())\n if reverse:\n ranked_values.reverse()\n ranked[x] = ranked_values.index(unranked[x]) + 1 # add 1 to account for zero indexing\n return ranked", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Great, but our data is structured such that it is indexed by player. But our ranking function takes a dictionary whose key is the stat category. \nLet's transpose our data so that this is the case:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "def transpose_players_to_categories(players):\n stat_categories = []\n for player in players:\n stat_categories = players[player].keys()\n break\n \n categories = {category: {} for category in stat_categories}\n\n for stat in players:\n for cat in stat_categories:\n try:\n categories[cat][stat] = int(str(players[stat][cat]))\n except ValueError:\n categories[cat][stat] = float(str(players[stat][cat]))\n \n return categories\n \nunranked_stats = transpose_players_to_categories(per_player_stats)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "OK, so now we have our data in the right format, but it's still just the totals. We haven't ranked it yet. Let's print it to take a look at what our data looks like:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "print_categories(unranked_stats, player_names)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Category</th><th>Dwayne Gretskeet</th><th>South Park Cows</th><th>the favorites</th><th>Pmoda</th><th>Fresh Baked Brownies</th><th>JoshHum</th><th>Pika Pikachus</th><th>BenDover</th><th>Mikhail's Team</th><th>First Place</th><th>Team Leaddz</th><th>EWeb FTW</th><th>HERRO. THIS IS DOG</th><th>Matthew's Team</th></tr><tr><td>A</td><td>191</td><td>191</td><td>153</td><td>186</td><td>185</td><td>198</td><td>201</td><td>206</td><td>160</td><td>214</td><td>156</td><td>149</td><td>148</td><td>169</td></tr><tr><td>+/-</td><td>26</td><td>46</td><td>82</td><td>-25</td><td>36</td><td>-22</td><td>59</td><td>74</td><td>40</td><td>-51</td><td>14</td><td>-28</td><td>51</td><td>9</td></tr><tr><td>PIM</td><td>379</td><td>282</td><td>307</td><td>318</td><td>262</td><td>227</td><td>177</td><td>248</td><td>268</td><td>186</td><td>279</td><td>164</td><td>245</td><td>256</td></tr><tr><td>G</td><td>154</td><td>141</td><td>132</td><td>124</td><td>95</td><td>121</td><td>113</td><td>119</td><td>138</td><td>88</td><td>81</td><td>81</td><td>83</td><td>89</td></tr><tr><td>SOG</td><td>1325</td><td>1157</td><td>1269</td><td>1283</td><td>1092</td><td>1263</td><td>1022</td><td>1064</td><td>1233</td><td>932</td><td>941</td><td>826</td><td>912</td><td>1052</td></tr><tr><td>SV%</td><td>0.926</td><td>0.92</td><td>0.918</td><td>0.919</td><td>0.926</td><td>0.914</td><td>0.91</td><td>0.905</td><td>0.9</td><td>0.909</td><td>0.906</td><td>0.909</td><td>0.914</td><td>0.898</td></tr><tr><td>PPP</td><td>109</td><td>115</td><td>76</td><td>97</td><td>91</td><td>115</td><td>103</td><td>88</td><td>97</td><td>108</td><td>72</td><td>70</td><td>70</td><td>97</td></tr><tr><td>W</td><td>38</td><td>31</td><td>33</td><td>32</td><td>25</td><td>21</td><td>21</td><td>22</td><td>13</td><td>29</td><td>16</td><td>26</td><td>19</td><td>13</td></tr><tr><td>GAA</td><td>2.32</td><td>2.57</td><td>2.23</td><td>2.11</td><td>2.01</td><td>2.93</td><td>2.65</td><td>2.52</td><td>2.88</td><td>2.64</td><td>2.61</td><td>2.4</td><td>2.84</td><td>3.11</td></tr><tr><td>SHO</td><td>4</td><td>4</td><td>5</td><td>4</td><td>5</td><td>2</td><td>2</td><td>0</td><td>3</td><td>2</td><td>2</td><td>5</td><td>2</td><td>1</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 6, | |
"text": "<IPython.core.display.HTML at 0x327a690>" | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Let's rank the data now. We're also going to rank all of our data in the opposite order in a seperate dictionary. I'll come back to why this is necessary a little later:\n(Notice that for GAA, lower is actually better, so we rank it in the other direction)" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "ranked_stats = {}\nfor stat in unranked_stats:\n if stat == \"GAA\":\n ranked_stats[stat] = rank(unranked_stats[stat], False)\n else:\n ranked_stats[stat] = rank(unranked_stats[stat])\n \nbackwards = {}\nfor stat in unranked_stats:\n if stat != \"GAA\":\n backwards[stat] = rank(unranked_stats[stat], False)\n else:\n backwards[stat] = rank(unranked_stats[stat])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Perfect, let's display it:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "print_categories(ranked_stats, player_names)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Category</th><th>Dwayne Gretskeet</th><th>South Park Cows</th><th>the favorites</th><th>Pmoda</th><th>Fresh Baked Brownies</th><th>JoshHum</th><th>Pika Pikachus</th><th>BenDover</th><th>Mikhail's Team</th><th>First Place</th><th>Team Leaddz</th><th>EWeb FTW</th><th>HERRO. THIS IS DOG</th><th>Matthew's Team</th></tr><tr><td>A</td><td>5</td><td>5</td><td>12</td><td>7</td><td>8</td><td>4</td><td>3</td><td>2</td><td>10</td><td>1</td><td>11</td><td>13</td><td>14</td><td>9</td></tr><tr><td>+/-</td><td>8</td><td>5</td><td>1</td><td>12</td><td>7</td><td>11</td><td>3</td><td>2</td><td>6</td><td>14</td><td>9</td><td>13</td><td>4</td><td>10</td></tr><tr><td>PIM</td><td>1</td><td>4</td><td>3</td><td>2</td><td>7</td><td>11</td><td>13</td><td>9</td><td>6</td><td>12</td><td>5</td><td>14</td><td>10</td><td>8</td></tr><tr><td>G</td><td>1</td><td>2</td><td>4</td><td>5</td><td>9</td><td>6</td><td>8</td><td>7</td><td>3</td><td>11</td><td>13</td><td>13</td><td>12</td><td>10</td></tr><tr><td>SOG</td><td>1</td><td>6</td><td>3</td><td>2</td><td>7</td><td>4</td><td>10</td><td>8</td><td>5</td><td>12</td><td>11</td><td>14</td><td>13</td><td>9</td></tr><tr><td>SV%</td><td>1</td><td>3</td><td>5</td><td>4</td><td>1</td><td>6</td><td>8</td><td>12</td><td>13</td><td>9</td><td>11</td><td>9</td><td>6</td><td>14</td></tr><tr><td>PPP</td><td>3</td><td>1</td><td>11</td><td>6</td><td>9</td><td>1</td><td>5</td><td>10</td><td>6</td><td>4</td><td>12</td><td>13</td><td>13</td><td>6</td></tr><tr><td>W</td><td>1</td><td>4</td><td>2</td><td>3</td><td>7</td><td>9</td><td>9</td><td>8</td><td>13</td><td>5</td><td>12</td><td>6</td><td>11</td><td>13</td></tr><tr><td>GAA</td><td>4</td><td>7</td><td>3</td><td>2</td><td>1</td><td>13</td><td>10</td><td>6</td><td>12</td><td>9</td><td>8</td><td>5</td><td>11</td><td>14</td></tr><tr><td>SHO</td><td>4</td><td>4</td><td>1</td><td>4</td><td>1</td><td>8</td><td>8</td><td>14</td><td>7</td><td>8</td><td>8</td><td>1</td><td>8</td><td>13</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 8, | |
"text": "<IPython.core.display.HTML at 0x3271f10>" | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "D'oh, so close! The data is still transposed. That's no good. Let's transpose it back to it's original format (and also transpose our backwards version while we're at it):" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "players = {player: {} for player in per_player_stats}\nfor stat in ranked_stats:\n for player in players:\n players[player][stat] = ranked_stats[stat][player]\n \nplayers_backwards = {player: {} for player in per_player_stats}\nfor stat in backwards:\n for player in players_backwards:\n players_backwards[player][stat] = backwards[stat][player]", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Awesome! Let's print out the results:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "print_players(players, scoring_categories)", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>G</th><th>A</th><th>+/-</th><th>PIM</th><th>PPP</th><th>SOG</th><th>W</th><th>GAA</th><th>SV%</th><th>SHO</th></tr><tr><td>Pmoda</td><td>5</td><td>7</td><td>12</td><td>2</td><td>6</td><td>2</td><td>3</td><td>2</td><td>4</td><td>4</td></tr><tr><td>Matthew's Team</td><td>10</td><td>9</td><td>10</td><td>8</td><td>6</td><td>9</td><td>13</td><td>14</td><td>14</td><td>13</td></tr><tr><td>South Park Cows</td><td>2</td><td>5</td><td>5</td><td>4</td><td>1</td><td>6</td><td>4</td><td>7</td><td>3</td><td>4</td></tr><tr><td>JoshHum</td><td>6</td><td>4</td><td>11</td><td>11</td><td>1</td><td>4</td><td>9</td><td>13</td><td>6</td><td>8</td></tr><tr><td>Dwayne Gretskeet</td><td>1</td><td>5</td><td>8</td><td>1</td><td>3</td><td>1</td><td>1</td><td>4</td><td>1</td><td>4</td></tr><tr><td>Fresh Baked Brownies</td><td>9</td><td>8</td><td>7</td><td>7</td><td>9</td><td>7</td><td>7</td><td>1</td><td>1</td><td>1</td></tr><tr><td>First Place</td><td>11</td><td>1</td><td>14</td><td>12</td><td>4</td><td>12</td><td>5</td><td>9</td><td>9</td><td>8</td></tr><tr><td>Mikhail's Team</td><td>3</td><td>10</td><td>6</td><td>6</td><td>6</td><td>5</td><td>13</td><td>12</td><td>13</td><td>7</td></tr><tr><td>the favorites</td><td>4</td><td>12</td><td>1</td><td>3</td><td>11</td><td>3</td><td>2</td><td>3</td><td>5</td><td>1</td></tr><tr><td>Pika Pikachus</td><td>8</td><td>3</td><td>3</td><td>13</td><td>5</td><td>10</td><td>9</td><td>10</td><td>8</td><td>8</td></tr><tr><td>BenDover</td><td>7</td><td>2</td><td>2</td><td>9</td><td>10</td><td>8</td><td>8</td><td>6</td><td>12</td><td>14</td></tr><tr><td>Team Leaddz</td><td>13</td><td>11</td><td>9</td><td>5</td><td>12</td><td>11</td><td>12</td><td>8</td><td>11</td><td>8</td></tr><tr><td>HERRO. THIS IS DOG</td><td>12</td><td>14</td><td>4</td><td>10</td><td>13</td><td>13</td><td>11</td><td>11</td><td>6</td><td>8</td></tr><tr><td>EWeb FTW</td><td>13</td><td>13</td><td>13</td><td>14</td><td>13</td><td>14</td><td>6</td><td>5</td><td>9</td><td>1</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 10, | |
"text": "<IPython.core.display.HTML at 0x327a8d0>" | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Super. We now have the basis for the rest of the work we're going to do. Let's try to add everyone's average rank:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "for player in players:\n avg = sum(players[player].values())/float(len(players[player].values()))\n avg = int(avg * 100) / 100.0 # trick to round to at most 2 decimal places\n players[player][\"AVG\"] = avg\nprint_players(players, [\"AVG\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>AVG</th></tr><tr><td>Pmoda</td><td>4.7</td></tr><tr><td>Matthew's Team</td><td>10.6</td></tr><tr><td>South Park Cows</td><td>4.09</td></tr><tr><td>JoshHum</td><td>7.3</td></tr><tr><td>Dwayne Gretskeet</td><td>2.9</td></tr><tr><td>Fresh Baked Brownies</td><td>5.7</td></tr><tr><td>First Place</td><td>8.5</td></tr><tr><td>Mikhail's Team</td><td>8.1</td></tr><tr><td>the favorites</td><td>4.5</td></tr><tr><td>Pika Pikachus</td><td>7.7</td></tr><tr><td>BenDover</td><td>7.8</td></tr><tr><td>Team Leaddz</td><td>10.0</td></tr><tr><td>HERRO. THIS IS DOG</td><td>10.19</td></tr><tr><td>EWeb FTW</td><td>10.1</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 11, | |
"text": "<IPython.core.display.HTML at 0x327c490>" | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Next, let's rank each player according to their average rank. At the same time I'm going to manually add in each player's actual rank according to Yahoo's scoring." | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "ranked_avg = rank(transpose_players_to_categories(players)[\"AVG\"], False)\n\nfor player in players:\n players[player][\"Rank\"] = ranked_avg[player]\n\nplayers[\"South Park Cows\"][\"Actual\"] = 1\nplayers[\"the favorites\"][\"Actual\"] = 2\nplayers[\"Dwayne Gretskeet\"][\"Actual\"] = 3\nplayers[\"Pmoda\"][\"Actual\"] = 4\nplayers[\"JoshHum\"][\"Actual\"] = 5\nplayers[\"Fresh Baked Brownies\"][\"Actual\"] = 6\nplayers[\"BenDover\"][\"Actual\"] = 7\nplayers[\"Mikhail's Team\"][\"Actual\"] = 8\nplayers[\"HERRO. THIS IS DOG\"][\"Actual\"] = 9\nplayers[\"First Place\"][\"Actual\"] = 10\nplayers[\"Pika Pikachus\"][\"Actual\"] = 11\nplayers[\"Matthew's Team\"][\"Actual\"] = 12\nplayers[\"EWeb FTW\"][\"Actual\"] = 13\nplayers[\"Team Leaddz\"][\"Actual\"] = 14\n\n \nprint_players(players, [\"AVG\", \"Rank\", \"Actual\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>AVG</th><th>Rank</th><th>Actual</th></tr><tr><td>Pmoda</td><td>4.7</td><td>4</td><td>4</td></tr><tr><td>Matthew's Team</td><td>10.6</td><td>14</td><td>12</td></tr><tr><td>South Park Cows</td><td>4.09</td><td>2</td><td>1</td></tr><tr><td>JoshHum</td><td>7.3</td><td>6</td><td>5</td></tr><tr><td>Dwayne Gretskeet</td><td>2.9</td><td>1</td><td>3</td></tr><tr><td>Fresh Baked Brownies</td><td>5.7</td><td>5</td><td>6</td></tr><tr><td>First Place</td><td>8.5</td><td>10</td><td>10</td></tr><tr><td>Mikhail's Team</td><td>8.1</td><td>9</td><td>8</td></tr><tr><td>the favorites</td><td>4.5</td><td>3</td><td>2</td></tr><tr><td>Pika Pikachus</td><td>7.7</td><td>7</td><td>11</td></tr><tr><td>BenDover</td><td>7.8</td><td>8</td><td>7</td></tr><tr><td>Team Leaddz</td><td>10.0</td><td>11</td><td>14</td></tr><tr><td>HERRO. THIS IS DOG</td><td>10.19</td><td>13</td><td>9</td></tr><tr><td>EWeb FTW</td><td>10.1</td><td>12</td><td>13</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 12, | |
"text": "<IPython.core.display.HTML at 0x3376c10>" | |
} | |
], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Alright, let's add everyone's diff between their Rank, and they Actual, Yahoo provided score:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "for player in players:\n players[player][\"Diff\"] = players[player][\"Rank\"] - players[player][\"Actual\"]\n \nprint_players(players, [\"AVG\", \"Rank\", \"Actual\", \"Diff\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>AVG</th><th>Rank</th><th>Actual</th><th>Diff</th></tr><tr><td>Pmoda</td><td>4.7</td><td>4</td><td>4</td><td>0</td></tr><tr><td>Matthew's Team</td><td>10.6</td><td>14</td><td>12</td><td>2</td></tr><tr><td>South Park Cows</td><td>4.09</td><td>2</td><td>1</td><td>1</td></tr><tr><td>JoshHum</td><td>7.3</td><td>6</td><td>5</td><td>1</td></tr><tr><td>Dwayne Gretskeet</td><td>2.9</td><td>1</td><td>3</td><td>-2</td></tr><tr><td>Fresh Baked Brownies</td><td>5.7</td><td>5</td><td>6</td><td>-1</td></tr><tr><td>First Place</td><td>8.5</td><td>10</td><td>10</td><td>0</td></tr><tr><td>Mikhail's Team</td><td>8.1</td><td>9</td><td>8</td><td>1</td></tr><tr><td>the favorites</td><td>4.5</td><td>3</td><td>2</td><td>1</td></tr><tr><td>Pika Pikachus</td><td>7.7</td><td>7</td><td>11</td><td>-4</td></tr><tr><td>BenDover</td><td>7.8</td><td>8</td><td>7</td><td>1</td></tr><tr><td>Team Leaddz</td><td>10.0</td><td>11</td><td>14</td><td>-3</td></tr><tr><td>HERRO. THIS IS DOG</td><td>10.19</td><td>13</td><td>9</td><td>4</td></tr><tr><td>EWeb FTW</td><td>10.1</td><td>12</td><td>13</td><td>-1</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 13, | |
"text": "<IPython.core.display.HTML at 0x335e710>" | |
} | |
], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Alright, let's add the final few pieces of the puzzle to get back to where the Excel version was at. First the easy part, number of First and Top 5s per player:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "for player in players:\n number_ones = 0\n top_fives = 0\n for cat in players[player]:\n if cat in scoring_categories:\n if players[player][cat] == 1:\n number_ones += 1\n if players[player][cat] < 6:\n top_fives += 1\n players[player][\"First\"] = number_ones\n players[player][\"Top 5\"] = top_fives\n \nprint_players(players, [\"AVG\", \"Rank\", \"Actual\", \"Diff\", \"First\", \"Top 5\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>AVG</th><th>Rank</th><th>Actual</th><th>Diff</th><th>First</th><th>Top 5</th></tr><tr><td>Pmoda</td><td>4.7</td><td>4</td><td>4</td><td>0</td><td>0</td><td>7</td></tr><tr><td>Matthew's Team</td><td>10.6</td><td>14</td><td>12</td><td>2</td><td>0</td><td>0</td></tr><tr><td>South Park Cows</td><td>4.09</td><td>2</td><td>1</td><td>1</td><td>1</td><td>8</td></tr><tr><td>JoshHum</td><td>7.3</td><td>6</td><td>5</td><td>1</td><td>1</td><td>3</td></tr><tr><td>Dwayne Gretskeet</td><td>2.9</td><td>1</td><td>3</td><td>-2</td><td>5</td><td>9</td></tr><tr><td>Fresh Baked Brownies</td><td>5.7</td><td>5</td><td>6</td><td>-1</td><td>3</td><td>3</td></tr><tr><td>First Place</td><td>8.5</td><td>10</td><td>10</td><td>0</td><td>1</td><td>3</td></tr><tr><td>Mikhail's Team</td><td>8.1</td><td>9</td><td>8</td><td>1</td><td>0</td><td>2</td></tr><tr><td>the favorites</td><td>4.5</td><td>3</td><td>2</td><td>1</td><td>2</td><td>8</td></tr><tr><td>Pika Pikachus</td><td>7.7</td><td>7</td><td>11</td><td>-4</td><td>0</td><td>3</td></tr><tr><td>BenDover</td><td>7.8</td><td>8</td><td>7</td><td>1</td><td>0</td><td>2</td></tr><tr><td>Team Leaddz</td><td>10.0</td><td>11</td><td>14</td><td>-3</td><td>0</td><td>1</td></tr><tr><td>HERRO. THIS IS DOG</td><td>10.19</td><td>13</td><td>9</td><td>4</td><td>0</td><td>1</td></tr><tr><td>EWeb FTW</td><td>10.1</td><td>12</td><td>13</td><td>-1</td><td>1</td><td>2</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 14, | |
"text": "<IPython.core.display.HTML at 0x327c4d0>" | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "It turns out getting the number of Last Place and Bottom 5 finishes is a bit trickier than First and Top 5. \nWe always know that the player with Rank == 1 is in First Place. Likewise, if someone's Rank is between 1 and 5 they are in the Top 5.\n\nBut is the opposite true for Last Place and Bottom 5? No -- because of ties. There are 14 Players, but if multiple people are tied for last, they're also tied for second to last, and are ranked as 13th rather than 14th.\n\nHey, remember that \"backwards\" stuff we did a while back? Well, now is when it's important. Ranked the opposite way, we're able to essentially treat Last and Bottom 5 exactly the same way as we did First and Top 5." | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "for player in players_backwards:\n lasts = 0\n bottom_fives = 0\n for cat in players_backwards[player]:\n if cat in scoring_categories:\n if players_backwards[player][cat] == 1:\n lasts += 1\n if players_backwards[player][cat] < 6:\n bottom_fives += 1\n players[player][\"Last\"] = lasts\n players[player][\"Bottom 5\"] = bottom_fives\n \nprint_players(players, [\"AVG\", \"Rank\", \"Actual\", \"Diff\", \"First\", \"Top 5\", \"Last\", \"Bottom 5\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>AVG</th><th>Rank</th><th>Actual</th><th>Diff</th><th>First</th><th>Top 5</th><th>Last</th><th>Bottom 5</th></tr><tr><td>Pmoda</td><td>4.7</td><td>4</td><td>4</td><td>0</td><td>0</td><td>7</td><td>0</td><td>1</td></tr><tr><td>Matthew's Team</td><td>10.6</td><td>14</td><td>12</td><td>2</td><td>0</td><td>0</td><td>3</td><td>6</td></tr><tr><td>South Park Cows</td><td>4.09</td><td>2</td><td>1</td><td>1</td><td>1</td><td>8</td><td>0</td><td>0</td></tr><tr><td>JoshHum</td><td>7.3</td><td>6</td><td>5</td><td>1</td><td>1</td><td>3</td><td>0</td><td>5</td></tr><tr><td>Dwayne Gretskeet</td><td>2.9</td><td>1</td><td>3</td><td>-2</td><td>5</td><td>9</td><td>0</td><td>0</td></tr><tr><td>Fresh Baked Brownies</td><td>5.7</td><td>5</td><td>6</td><td>-1</td><td>3</td><td>3</td><td>0</td><td>0</td></tr><tr><td>First Place</td><td>8.5</td><td>10</td><td>10</td><td>0</td><td>1</td><td>3</td><td>1</td><td>6</td></tr><tr><td>Mikhail's Team</td><td>8.1</td><td>9</td><td>8</td><td>1</td><td>0</td><td>2</td><td>1</td><td>4</td></tr><tr><td>the favorites</td><td>4.5</td><td>3</td><td>2</td><td>1</td><td>2</td><td>8</td><td>0</td><td>2</td></tr><tr><td>Pika Pikachus</td><td>7.7</td><td>7</td><td>11</td><td>-4</td><td>0</td><td>3</td><td>0</td><td>5</td></tr><tr><td>BenDover</td><td>7.8</td><td>8</td><td>7</td><td>1</td><td>0</td><td>2</td><td>1</td><td>3</td></tr><tr><td>Team Leaddz</td><td>10.0</td><td>11</td><td>14</td><td>-3</td><td>0</td><td>1</td><td>1</td><td>7</td></tr><tr><td>HERRO. THIS IS DOG</td><td>10.19</td><td>13</td><td>9</td><td>4</td><td>0</td><td>1</td><td>2</td><td>8</td></tr><tr><td>EWeb FTW</td><td>10.1</td><td>12</td><td>13</td><td>-1</td><td>1</td><td>2</td><td>4</td><td>7</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 15, | |
"text": "<IPython.core.display.HTML at 0x327c850>" | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Alright, let's take a look at everything all together now:" | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": "print_players(players, scoring_categories + [\"AVG\", \"Rank\", \"Actual\", \"Diff\", \"First\", \"Top 5\", \"Last\", \"Bottom 5\"])", | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": "<table><tr><th>Player</th><th>G</th><th>A</th><th>+/-</th><th>PIM</th><th>PPP</th><th>SOG</th><th>W</th><th>GAA</th><th>SV%</th><th>SHO</th><th>AVG</th><th>Rank</th><th>Actual</th><th>Diff</th><th>First</th><th>Top 5</th><th>Last</th><th>Bottom 5</th></tr><tr><td>Pmoda</td><td>5</td><td>7</td><td>12</td><td>2</td><td>6</td><td>2</td><td>3</td><td>2</td><td>4</td><td>4</td><td>4.7</td><td>4</td><td>4</td><td>0</td><td>0</td><td>7</td><td>0</td><td>1</td></tr><tr><td>Matthew's Team</td><td>10</td><td>9</td><td>10</td><td>8</td><td>6</td><td>9</td><td>13</td><td>14</td><td>14</td><td>13</td><td>10.6</td><td>14</td><td>12</td><td>2</td><td>0</td><td>0</td><td>3</td><td>6</td></tr><tr><td>South Park Cows</td><td>2</td><td>5</td><td>5</td><td>4</td><td>1</td><td>6</td><td>4</td><td>7</td><td>3</td><td>4</td><td>4.09</td><td>2</td><td>1</td><td>1</td><td>1</td><td>8</td><td>0</td><td>0</td></tr><tr><td>JoshHum</td><td>6</td><td>4</td><td>11</td><td>11</td><td>1</td><td>4</td><td>9</td><td>13</td><td>6</td><td>8</td><td>7.3</td><td>6</td><td>5</td><td>1</td><td>1</td><td>3</td><td>0</td><td>5</td></tr><tr><td>Dwayne Gretskeet</td><td>1</td><td>5</td><td>8</td><td>1</td><td>3</td><td>1</td><td>1</td><td>4</td><td>1</td><td>4</td><td>2.9</td><td>1</td><td>3</td><td>-2</td><td>5</td><td>9</td><td>0</td><td>0</td></tr><tr><td>Fresh Baked Brownies</td><td>9</td><td>8</td><td>7</td><td>7</td><td>9</td><td>7</td><td>7</td><td>1</td><td>1</td><td>1</td><td>5.7</td><td>5</td><td>6</td><td>-1</td><td>3</td><td>3</td><td>0</td><td>0</td></tr><tr><td>First Place</td><td>11</td><td>1</td><td>14</td><td>12</td><td>4</td><td>12</td><td>5</td><td>9</td><td>9</td><td>8</td><td>8.5</td><td>10</td><td>10</td><td>0</td><td>1</td><td>3</td><td>1</td><td>6</td></tr><tr><td>Mikhail's Team</td><td>3</td><td>10</td><td>6</td><td>6</td><td>6</td><td>5</td><td>13</td><td>12</td><td>13</td><td>7</td><td>8.1</td><td>9</td><td>8</td><td>1</td><td>0</td><td>2</td><td>1</td><td>4</td></tr><tr><td>the favorites</td><td>4</td><td>12</td><td>1</td><td>3</td><td>11</td><td>3</td><td>2</td><td>3</td><td>5</td><td>1</td><td>4.5</td><td>3</td><td>2</td><td>1</td><td>2</td><td>8</td><td>0</td><td>2</td></tr><tr><td>Pika Pikachus</td><td>8</td><td>3</td><td>3</td><td>13</td><td>5</td><td>10</td><td>9</td><td>10</td><td>8</td><td>8</td><td>7.7</td><td>7</td><td>11</td><td>-4</td><td>0</td><td>3</td><td>0</td><td>5</td></tr><tr><td>BenDover</td><td>7</td><td>2</td><td>2</td><td>9</td><td>10</td><td>8</td><td>8</td><td>6</td><td>12</td><td>14</td><td>7.8</td><td>8</td><td>7</td><td>1</td><td>0</td><td>2</td><td>1</td><td>3</td></tr><tr><td>Team Leaddz</td><td>13</td><td>11</td><td>9</td><td>5</td><td>12</td><td>11</td><td>12</td><td>8</td><td>11</td><td>8</td><td>10.0</td><td>11</td><td>14</td><td>-3</td><td>0</td><td>1</td><td>1</td><td>7</td></tr><tr><td>HERRO. THIS IS DOG</td><td>12</td><td>14</td><td>4</td><td>10</td><td>13</td><td>13</td><td>11</td><td>11</td><td>6</td><td>8</td><td>10.19</td><td>13</td><td>9</td><td>4</td><td>0</td><td>1</td><td>2</td><td>8</td></tr><tr><td>EWeb FTW</td><td>13</td><td>13</td><td>13</td><td>14</td><td>13</td><td>14</td><td>6</td><td>5</td><td>9</td><td>1</td><td>10.1</td><td>12</td><td>13</td><td>-1</td><td>1</td><td>2</td><td>4</td><td>7</td></tr></table>", | |
"output_type": "pyout", | |
"prompt_number": 16, | |
"text": "<IPython.core.display.HTML at 0x327ad50>" | |
} | |
], | |
"prompt_number": 16 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": "Conclusion" | |
}, | |
{ | |
"cell_type": "raw", | |
"metadata": {}, | |
"source": "Aaanndddd, we're back to where we were with the Excel version. Wow, that took a bit longer than expected. It was fun, but took quite a bit more effort than the Excel version did. Lessons learned? Probably, but it's 5am and I'm going to sleep.\n\nThanks for reading!" | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment