BraydenMoore commited on
Commit
6249340
β€’
1 Parent(s): c2c6692

Update with up to date data

Browse files
Files changed (47) hide show
  1. Source/Data/gbg_and_odds_this_year.csv +0 -0
  2. Source/Data/gbg_this_year.csv +0 -0
  3. Source/Data/lines.json +202 -202
  4. Source/Data/results.csv +193 -3
  5. Source/Pickles/schedule.pkl +0 -0
  6. Source/Pickles/team_abbreviation_to_name.pkl +0 -0
  7. Source/Pickles/team_name_to_abbreviation.pkl +0 -0
  8. Source/Pickles/test_games_ATS_no_odds.pkl +0 -0
  9. Source/Pickles/test_games_ML.pkl +0 -0
  10. Source/Pickles/test_games_ML_no_odds.pkl +0 -0
  11. Source/Pickles/test_games_ML_no_odds_56.8%.pkl +0 -0
  12. Source/Pickles/test_games_ML_no_odds_60.8%.pkl +0 -0
  13. Source/Pickles/test_games_ML_no_odds_61.3%.pkl +0 -0
  14. Source/Pickles/test_games_ML_no_odds_62.3%.pkl +0 -0
  15. Source/Pickles/test_games_ML_no_odds_63.3%.pkl +0 -0
  16. Source/Pickles/test_games_ML_no_odds_63.8%.pkl +0 -0
  17. Source/Pickles/test_games_ML_no_odds_64.3%.pkl +0 -0
  18. Source/Pickles/test_games_ML_no_odds_64.8%.pkl +0 -0
  19. Source/Pickles/test_games_ML_no_odds_66.3%.pkl +0 -0
  20. Source/Pickles/test_games_ML_no_odds_66.8%.pkl +0 -0
  21. Source/Pickles/test_games_ML_no_odds_68.8%.pkl +0 -0
  22. Source/Pickles/test_games_ML_no_odds_69.3%.pkl +0 -0
  23. Source/Pickles/test_games_ML_no_odds_70.4%.pkl +0 -0
  24. Source/Pickles/test_games_OU.pkl +0 -0
  25. Source/Pickles/test_games_OU_no_odds.pkl +0 -0
  26. Source/Pickles/the_week.pkl +0 -0
  27. Source/Pickles/train_games_ATS_no_odds.pkl +0 -0
  28. Source/Pickles/train_games_ML.pkl +0 -0
  29. Source/Pickles/train_games_ML_no_odds.pkl +0 -0
  30. Source/Pickles/train_games_ML_no_odds_56.8%.pkl +0 -0
  31. Source/Pickles/train_games_ML_no_odds_60.8%.pkl +0 -0
  32. Source/Pickles/train_games_ML_no_odds_61.3%.pkl +0 -0
  33. Source/Pickles/train_games_ML_no_odds_62.3%.pkl +0 -0
  34. Source/Pickles/train_games_ML_no_odds_63.3%.pkl +0 -0
  35. Source/Pickles/train_games_ML_no_odds_63.8%.pkl +0 -0
  36. Source/Pickles/train_games_ML_no_odds_64.3%.pkl +0 -0
  37. Source/Pickles/train_games_ML_no_odds_64.8%.pkl +0 -0
  38. Source/Pickles/train_games_ML_no_odds_66.3%.pkl +0 -0
  39. Source/Pickles/train_games_ML_no_odds_66.8%.pkl +0 -0
  40. Source/Pickles/train_games_ML_no_odds_68.8%.pkl +0 -0
  41. Source/Pickles/train_games_ML_no_odds_69.3%.pkl +0 -0
  42. Source/Pickles/train_games_ML_no_odds_70.4%.pkl +0 -0
  43. Source/Pickles/train_games_OU.pkl +0 -0
  44. Source/Pickles/train_games_OU_no_odds.pkl +0 -0
  45. Static/Over_Under_Predictions_dark.png +0 -0
  46. Static/Winner_Predictions_dark.png +0 -0
  47. Templates/index.html +724 -724
Source/Data/gbg_and_odds_this_year.csv CHANGED
The diff for this file is too large to render. See raw diff
 
Source/Data/gbg_this_year.csv CHANGED
The diff for this file is too large to render. See raw diff
 
Source/Data/lines.json CHANGED
@@ -1,203 +1,203 @@
1
- {
2
- "2":[
3
- 49,
4
- 40.5,
5
- 47,
6
- 45.5,
7
- 47,
8
- 39.5,
9
- 51.5,
10
- 41,
11
- 45,
12
- 40,
13
- 44.5,
14
- 39,
15
- 37.5,
16
- 47,
17
- 39.5,
18
- 39
19
- ],
20
- "3":[
21
- 44.5,
22
- 43,
23
- 38,
24
- 47,
25
- 41.5,
26
- 43.5,
27
- 47.5,
28
- 54.5,
29
- 35,
30
- 43,
31
- 42.5,
32
- 44,
33
- 48.8,
34
- 43.5,
35
- 45,
36
- 43.5
37
- ],
38
- "4":[
39
- 45.5,
40
- 42.5,
41
- 53.5,
42
- 46,
43
- 47,
44
- 39,
45
- 42,
46
- 45.5,
47
- 40,
48
- 43.0,
49
- 41.5,
50
- 48,
51
- 43.5,
52
- 43.5,
53
- 41.5,
54
- 47
55
- ],
56
- "5":[
57
- 45,
58
- 48,
59
- 41.5,
60
- 44,
61
- 43,
62
- 47.5,
63
- 39.5,
64
- 38,
65
- 44.5,
66
- 50,
67
- 43,
68
- 53,
69
- 45.5,
70
- 45
71
- ],
72
- "6":[
73
- 46.5,
74
- 42.5,
75
- 42.5,
76
- 43.5,
77
- 44.5,
78
- 36,
79
- 42.5,
80
- 43.5,
81
- 47,
82
- 41.5,
83
- 42.5,
84
- 48,
85
- 42.5,
86
- 43.5,
87
- 51
88
- ],
89
- "7":[
90
- 40.5,
91
- 43,
92
- 37.5,
93
- 41,
94
- 40,
95
- 37,
96
- 37,
97
- 44,
98
- 44,
99
- 45,
100
- 47.5,
101
- 51,
102
- 44
103
- ],
104
- "8":[
105
- 43.5,
106
- 44,
107
- 46,
108
- 41.5,
109
- 43.5,
110
- 46.5,
111
- 35.5,
112
- 40.5,
113
- 35.5,
114
- 43,
115
- 37.5,
116
- 44.5,
117
- 45.5,
118
- 43.5,
119
- 46.5,
120
- 46.5
121
- ],
122
- "9":[
123
- 37,
124
- 50,
125
- 37.5,
126
- 44,
127
- 38.5,
128
- 38,
129
- 40,
130
- 41,
131
- 41,
132
- 44,
133
- 38,
134
- 47,
135
- 50.5,
136
- 40
137
- ],
138
- "10":[
139
- 38,
140
- 42,
141
- 38,
142
- 46.5,
143
- 45,
144
- 41,
145
- 38,
146
- 39.5,
147
- 44,
148
- 48,
149
- 38.5,
150
- 44.5,
151
- 36.5,
152
- 46
153
- ],
154
- "11":[
155
- 46.5,
156
- 43.5,
157
- 34.5,
158
- 47.5,
159
- 43.5,
160
- 48,
161
- 40,
162
- 44.5,
163
- 38.5,
164
- 41.5,
165
- 39.5,
166
- 45.5,
167
- 42.5,
168
- 45.5
169
- ],
170
- "12":[
171
- 48,
172
- 48.5,
173
- 44.5,
174
- 40.5,
175
- 42,
176
- 35.5,
177
- 48,
178
- 44.5,
179
- 33.5,
180
- 36.5,
181
- 44.5,
182
- 36,
183
- 42.5,
184
- 48.5,
185
- 48,
186
- 43
187
- ],
188
- "13":[
189
- 47.5,
190
- 39,
191
- 47.5,
192
- 33,
193
- 41,
194
- 42,
195
- 49.5,
196
- 47,
197
- 37,
198
- 47,
199
- 40,
200
- 43,
201
- 39
202
- ]
203
  }
 
1
+ {
2
+ "2":[
3
+ 49,
4
+ 40.5,
5
+ 47,
6
+ 45.5,
7
+ 47,
8
+ 39.5,
9
+ 51.5,
10
+ 41,
11
+ 45,
12
+ 40,
13
+ 44.5,
14
+ 39,
15
+ 37.5,
16
+ 47,
17
+ 39.5,
18
+ 39
19
+ ],
20
+ "3":[
21
+ 44.5,
22
+ 43,
23
+ 38,
24
+ 47,
25
+ 41.5,
26
+ 43.5,
27
+ 47.5,
28
+ 54.5,
29
+ 35,
30
+ 43,
31
+ 42.5,
32
+ 44,
33
+ 48.8,
34
+ 43.5,
35
+ 45,
36
+ 43.5
37
+ ],
38
+ "4":[
39
+ 45.5,
40
+ 42.5,
41
+ 53.5,
42
+ 46,
43
+ 47,
44
+ 39,
45
+ 42,
46
+ 45.5,
47
+ 40,
48
+ 43.0,
49
+ 41.5,
50
+ 48,
51
+ 43.5,
52
+ 43.5,
53
+ 41.5,
54
+ 47
55
+ ],
56
+ "5":[
57
+ 45,
58
+ 48,
59
+ 41.5,
60
+ 44,
61
+ 43,
62
+ 47.5,
63
+ 39.5,
64
+ 38,
65
+ 44.5,
66
+ 50,
67
+ 43,
68
+ 53,
69
+ 45.5,
70
+ 45
71
+ ],
72
+ "6":[
73
+ 46.5,
74
+ 42.5,
75
+ 42.5,
76
+ 43.5,
77
+ 44.5,
78
+ 36,
79
+ 42.5,
80
+ 43.5,
81
+ 47,
82
+ 41.5,
83
+ 42.5,
84
+ 48,
85
+ 42.5,
86
+ 43.5,
87
+ 51
88
+ ],
89
+ "7":[
90
+ 40.5,
91
+ 43,
92
+ 37.5,
93
+ 41,
94
+ 40,
95
+ 37,
96
+ 37,
97
+ 44,
98
+ 44,
99
+ 45,
100
+ 47.5,
101
+ 51,
102
+ 44
103
+ ],
104
+ "8":[
105
+ 43.5,
106
+ 44,
107
+ 46,
108
+ 41.5,
109
+ 43.5,
110
+ 46.5,
111
+ 35.5,
112
+ 40.5,
113
+ 35.5,
114
+ 43,
115
+ 37.5,
116
+ 44.5,
117
+ 45.5,
118
+ 43.5,
119
+ 46.5,
120
+ 46.5
121
+ ],
122
+ "9":[
123
+ 37,
124
+ 50,
125
+ 37.5,
126
+ 44,
127
+ 38.5,
128
+ 38,
129
+ 40,
130
+ 41,
131
+ 41,
132
+ 44,
133
+ 38,
134
+ 47,
135
+ 50.5,
136
+ 40
137
+ ],
138
+ "10":[
139
+ 38,
140
+ 42,
141
+ 38,
142
+ 46.5,
143
+ 45,
144
+ 41,
145
+ 38,
146
+ 39.5,
147
+ 44,
148
+ 48,
149
+ 38.5,
150
+ 44.5,
151
+ 36.5,
152
+ 46
153
+ ],
154
+ "11":[
155
+ 46.5,
156
+ 43.5,
157
+ 34.5,
158
+ 47.5,
159
+ 43.5,
160
+ 48,
161
+ 40,
162
+ 44.5,
163
+ 38.5,
164
+ 41.5,
165
+ 39.5,
166
+ 45.5,
167
+ 42.5,
168
+ 45.5
169
+ ],
170
+ "12":[
171
+ 48,
172
+ 48.5,
173
+ 44.5,
174
+ 40.5,
175
+ 42,
176
+ 35.5,
177
+ 48,
178
+ 44.5,
179
+ 33.5,
180
+ 36.5,
181
+ 44.5,
182
+ 36,
183
+ 42.5,
184
+ 48.5,
185
+ 48,
186
+ 43
187
+ ],
188
+ "13":[
189
+ 47.5,
190
+ 39,
191
+ 47.5,
192
+ 33,
193
+ 41,
194
+ 42,
195
+ 49.5,
196
+ 47,
197
+ 37,
198
+ 47,
199
+ 40,
200
+ 43,
201
+ 39
202
+ ]
203
  }
Source/Data/results.csv CHANGED
@@ -1,3 +1,193 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:dba9bb6b4464d0923fccdd8ed42b883ce14a923ee66cddbaa30e5ac21f317848
3
- size 6731
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ game_id,total,winner
2
+ 2023_01_ARI_WAS,36,Washington Commanders
3
+ 2023_01_BUF_NYJ,38,New York Jets
4
+ 2023_01_CAR_ATL,34,Atlanta Falcons
5
+ 2023_01_CIN_CLE,27,Cleveland Browns
6
+ 2023_01_DAL_NYG,40,Dallas Cowboys
7
+ 2023_01_DET_KC,41,Detroit Lions
8
+ 2023_01_GB_CHI,58,Green Bay Packers
9
+ 2023_01_HOU_BAL,34,Baltimore Ravens
10
+ 2023_01_JAX_IND,52,Jacksonville Jaguars
11
+ 2023_01_LA_SEA,43,Los Angeles Rams
12
+ 2023_01_LV_DEN,33,Las Vegas Raiders
13
+ 2023_01_MIA_LAC,70,Miami Dolphins
14
+ 2023_01_PHI_NE,45,Philadelphia Eagles
15
+ 2023_01_SF_PIT,37,San Francisco 49ers
16
+ 2023_01_TB_MIN,37,Tampa Bay Buccaneers
17
+ 2023_01_TEN_NO,31,New Orleans Saints
18
+ 2023_02_BAL_CIN,51,Baltimore Ravens
19
+ 2023_02_CHI_TB,44,Tampa Bay Buccaneers
20
+ 2023_02_CLE_PIT,48,Pittsburgh Steelers
21
+ 2023_02_GB_ATL,49,Atlanta Falcons
22
+ 2023_02_IND_HOU,51,Indianapolis Colts
23
+ 2023_02_KC_JAX,26,Kansas City Chiefs
24
+ 2023_02_LAC_TEN,51,Tennessee Titans
25
+ 2023_02_LV_BUF,48,Buffalo Bills
26
+ 2023_02_MIA_NE,41,Miami Dolphins
27
+ 2023_02_MIN_PHI,62,Philadelphia Eagles
28
+ 2023_02_NO_CAR,37,New Orleans Saints
29
+ 2023_02_NYG_ARI,59,New York Giants
30
+ 2023_02_NYJ_DAL,40,Dallas Cowboys
31
+ 2023_02_SEA_DET,68,Seattle Seahawks
32
+ 2023_02_SF_LA,53,San Francisco 49ers
33
+ 2023_02_WAS_DEN,68,Washington Commanders
34
+ 2023_03_ATL_DET,26,Detroit Lions
35
+ 2023_03_BUF_WAS,40,Buffalo Bills
36
+ 2023_03_CAR_SEA,64,Seattle Seahawks
37
+ 2023_03_CHI_KC,51,Kansas City Chiefs
38
+ 2023_03_DAL_ARI,44,Arizona Cardinals
39
+ 2023_03_DEN_MIA,90,Miami Dolphins
40
+ 2023_03_HOU_JAX,54,Houston Texans
41
+ 2023_03_IND_BAL,41,Indianapolis Colts
42
+ 2023_03_LAC_MIN,52,Los Angeles Chargers
43
+ 2023_03_LA_CIN,35,Cincinnati Bengals
44
+ 2023_03_NE_NYJ,25,New England Patriots
45
+ 2023_03_NO_GB,35,Green Bay Packers
46
+ 2023_03_NYG_SF,42,San Francisco 49ers
47
+ 2023_03_PHI_TB,36,Philadelphia Eagles
48
+ 2023_03_PIT_LV,41,Pittsburgh Steelers
49
+ 2023_03_TEN_CLE,30,Cleveland Browns
50
+ 2023_04_ARI_SF,51,San Francisco 49ers
51
+ 2023_04_ATL_JAX,30,Jacksonville Jaguars
52
+ 2023_04_BAL_CLE,31,Baltimore Ravens
53
+ 2023_04_CIN_TEN,30,Tennessee Titans
54
+ 2023_04_DEN_CHI,59,Denver Broncos
55
+ 2023_04_DET_GB,54,Detroit Lions
56
+ 2023_04_KC_NYJ,43,Kansas City Chiefs
57
+ 2023_04_LA_IND,52,Los Angeles Rams
58
+ 2023_04_LV_LAC,41,Los Angeles Chargers
59
+ 2023_04_MIA_BUF,68,Buffalo Bills
60
+ 2023_04_MIN_CAR,34,Minnesota Vikings
61
+ 2023_04_NE_DAL,41,Dallas Cowboys
62
+ 2023_04_PIT_HOU,36,Houston Texans
63
+ 2023_04_SEA_NYG,27,Seattle Seahawks
64
+ 2023_04_TB_NO,35,Tampa Bay Buccaneers
65
+ 2023_04_WAS_PHI,65,Philadelphia Eagles
66
+ 2023_05_BAL_PIT,27,Pittsburgh Steelers
67
+ 2023_05_CAR_DET,66,Detroit Lions
68
+ 2023_05_CHI_WAS,60,Chicago Bears
69
+ 2023_05_CIN_ARI,54,Cincinnati Bengals
70
+ 2023_05_DAL_SF,52,San Francisco 49ers
71
+ 2023_05_GB_LV,30,Las Vegas Raiders
72
+ 2023_05_HOU_ATL,40,Atlanta Falcons
73
+ 2023_05_JAX_BUF,45,Jacksonville Jaguars
74
+ 2023_05_KC_MIN,47,Kansas City Chiefs
75
+ 2023_05_NO_NE,34,New Orleans Saints
76
+ 2023_05_NYG_MIA,47,Miami Dolphins
77
+ 2023_05_NYJ_DEN,52,New York Jets
78
+ 2023_05_PHI_LA,37,Philadelphia Eagles
79
+ 2023_05_TEN_IND,39,Indianapolis Colts
80
+ 2023_06_ARI_LA,35,Los Angeles Rams
81
+ 2023_06_BAL_TEN,40,Baltimore Ravens
82
+ 2023_06_CAR_MIA,63,Miami Dolphins
83
+ 2023_06_DAL_LAC,37,Dallas Cowboys
84
+ 2023_06_DEN_KC,27,Kansas City Chiefs
85
+ 2023_06_DET_TB,26,Detroit Lions
86
+ 2023_06_IND_JAX,57,Jacksonville Jaguars
87
+ 2023_06_MIN_CHI,32,Minnesota Vikings
88
+ 2023_06_NE_LV,38,Las Vegas Raiders
89
+ 2023_06_NO_HOU,33,Houston Texans
90
+ 2023_06_NYG_BUF,23,Buffalo Bills
91
+ 2023_06_PHI_NYJ,34,New York Jets
92
+ 2023_06_SEA_CIN,30,Cincinnati Bengals
93
+ 2023_06_SF_CLE,36,Cleveland Browns
94
+ 2023_06_WAS_ATL,40,Washington Commanders
95
+ 2023_07_ARI_SEA,30,Seattle Seahawks
96
+ 2023_07_ATL_TB,29,Atlanta Falcons
97
+ 2023_07_BUF_NE,54,New England Patriots
98
+ 2023_07_CLE_IND,77,Cleveland Browns
99
+ 2023_07_DET_BAL,44,Baltimore Ravens
100
+ 2023_07_GB_DEN,36,Denver Broncos
101
+ 2023_07_JAX_NO,55,Jacksonville Jaguars
102
+ 2023_07_LAC_KC,48,Kansas City Chiefs
103
+ 2023_07_LV_CHI,42,Chicago Bears
104
+ 2023_07_MIA_PHI,48,Philadelphia Eagles
105
+ 2023_07_PIT_LA,41,Pittsburgh Steelers
106
+ 2023_07_SF_MIN,39,Minnesota Vikings
107
+ 2023_07_WAS_NYG,21,New York Giants
108
+ 2023_08_ATL_TEN,51,Tennessee Titans
109
+ 2023_08_BAL_ARI,55,Baltimore Ravens
110
+ 2023_08_CHI_LAC,43,Los Angeles Chargers
111
+ 2023_08_CIN_SF,48,Cincinnati Bengals
112
+ 2023_08_CLE_SEA,44,Seattle Seahawks
113
+ 2023_08_HOU_CAR,28,Carolina Panthers
114
+ 2023_08_JAX_PIT,30,Jacksonville Jaguars
115
+ 2023_08_KC_DEN,33,Denver Broncos
116
+ 2023_08_LA_DAL,63,Dallas Cowboys
117
+ 2023_08_LV_DET,40,Detroit Lions
118
+ 2023_08_MIN_GB,34,Minnesota Vikings
119
+ 2023_08_NE_MIA,48,Miami Dolphins
120
+ 2023_08_NO_IND,65,New Orleans Saints
121
+ 2023_08_NYJ_NYG,23,New York Jets
122
+ 2023_08_PHI_WAS,69,Philadelphia Eagles
123
+ 2023_08_TB_BUF,42,Buffalo Bills
124
+ 2023_09_ARI_CLE,27,Cleveland Browns
125
+ 2023_09_BUF_CIN,42,Cincinnati Bengals
126
+ 2023_09_CHI_NO,41,New Orleans Saints
127
+ 2023_09_DAL_PHI,51,Philadelphia Eagles
128
+ 2023_09_IND_CAR,40,Indianapolis Colts
129
+ 2023_09_LAC_NYJ,33,Los Angeles Chargers
130
+ 2023_09_LA_GB,23,Green Bay Packers
131
+ 2023_09_MIA_KC,35,Kansas City Chiefs
132
+ 2023_09_MIN_ATL,59,Minnesota Vikings
133
+ 2023_09_NYG_LV,36,Las Vegas Raiders
134
+ 2023_09_SEA_BAL,40,Baltimore Ravens
135
+ 2023_09_TB_HOU,76,Houston Texans
136
+ 2023_09_TEN_PIT,36,Pittsburgh Steelers
137
+ 2023_09_WAS_NE,37,Washington Commanders
138
+ 2023_10_ATL_ARI,48,Arizona Cardinals
139
+ 2023_10_CAR_CHI,29,Chicago Bears
140
+ 2023_10_CLE_BAL,64,Cleveland Browns
141
+ 2023_10_DEN_BUF,46,Denver Broncos
142
+ 2023_10_DET_LAC,79,Detroit Lions
143
+ 2023_10_GB_PIT,42,Pittsburgh Steelers
144
+ 2023_10_HOU_CIN,57,Houston Texans
145
+ 2023_10_IND_NE,16,Indianapolis Colts
146
+ 2023_10_NO_MIN,46,Minnesota Vikings
147
+ 2023_10_NYG_DAL,66,Dallas Cowboys
148
+ 2023_10_NYJ_LV,28,Las Vegas Raiders
149
+ 2023_10_SF_JAX,37,San Francisco 49ers
150
+ 2023_10_TEN_TB,26,Tampa Bay Buccaneers
151
+ 2023_10_WAS_SEA,55,Seattle Seahawks
152
+ 2023_11_ARI_HOU,37,Houston Texans
153
+ 2023_11_CHI_DET,57,Detroit Lions
154
+ 2023_11_CIN_BAL,54,Baltimore Ravens
155
+ 2023_11_DAL_CAR,43,Dallas Cowboys
156
+ 2023_11_LAC_GB,43,Green Bay Packers
157
+ 2023_11_LV_MIA,33,Miami Dolphins
158
+ 2023_11_MIN_DEN,41,Denver Broncos
159
+ 2023_11_NYG_WAS,50,New York Giants
160
+ 2023_11_NYJ_BUF,38,Buffalo Bills
161
+ 2023_11_PHI_KC,38,Philadelphia Eagles
162
+ 2023_11_PIT_CLE,23,Cleveland Browns
163
+ 2023_11_SEA_LA,33,Los Angeles Rams
164
+ 2023_11_TB_SF,41,San Francisco 49ers
165
+ 2023_11_TEN_JAX,48,Jacksonville Jaguars
166
+ 2023_12_BAL_LAC,30,Baltimore Ravens
167
+ 2023_12_BUF_PHI,71,Philadelphia Eagles
168
+ 2023_12_CAR_TEN,27,Tennessee Titans
169
+ 2023_12_CHI_MIN,22,Chicago Bears
170
+ 2023_12_CLE_DEN,41,Denver Broncos
171
+ 2023_12_GB_DET,51,Green Bay Packers
172
+ 2023_12_JAX_HOU,45,Jacksonville Jaguars
173
+ 2023_12_KC_LV,48,Kansas City Chiefs
174
+ 2023_12_LA_ARI,51,Los Angeles Rams
175
+ 2023_12_MIA_NYJ,47,Miami Dolphins
176
+ 2023_12_NE_NYG,17,New York Giants
177
+ 2023_12_NO_ATL,39,Atlanta Falcons
178
+ 2023_12_PIT_CIN,26,Pittsburgh Steelers
179
+ 2023_12_SF_SEA,44,San Francisco 49ers
180
+ 2023_12_TB_IND,47,Indianapolis Colts
181
+ 2023_12_WAS_DAL,55,Dallas Cowboys
182
+ 2023_13_ARI_PIT,34,Arizona Cardinals
183
+ 2023_13_ATL_NYJ,21,Atlanta Falcons
184
+ 2023_13_CAR_TB,39,Tampa Bay Buccaneers
185
+ 2023_13_CLE_LA,55,Los Angeles Rams
186
+ 2023_13_DEN_HOU,39,Houston Texans
187
+ 2023_13_DET_NO,61,Detroit Lions
188
+ 2023_13_IND_TEN,59,Indianapolis Colts
189
+ 2023_13_KC_GB,46,Green Bay Packers
190
+ 2023_13_LAC_NE,6,Los Angeles Chargers
191
+ 2023_13_MIA_WAS,60,Miami Dolphins
192
+ 2023_13_SEA_DAL,76,Dallas Cowboys
193
+ 2023_13_SF_PHI,61,San Francisco 49ers
Source/Pickles/schedule.pkl CHANGED
Binary files a/Source/Pickles/schedule.pkl and b/Source/Pickles/schedule.pkl differ
 
Source/Pickles/team_abbreviation_to_name.pkl CHANGED
Binary files a/Source/Pickles/team_abbreviation_to_name.pkl and b/Source/Pickles/team_abbreviation_to_name.pkl differ
 
Source/Pickles/team_name_to_abbreviation.pkl CHANGED
Binary files a/Source/Pickles/team_name_to_abbreviation.pkl and b/Source/Pickles/team_name_to_abbreviation.pkl differ
 
Source/Pickles/test_games_ATS_no_odds.pkl CHANGED
Binary files a/Source/Pickles/test_games_ATS_no_odds.pkl and b/Source/Pickles/test_games_ATS_no_odds.pkl differ
 
Source/Pickles/test_games_ML.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML.pkl and b/Source/Pickles/test_games_ML.pkl differ
 
Source/Pickles/test_games_ML_no_odds.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds.pkl and b/Source/Pickles/test_games_ML_no_odds.pkl differ
 
Source/Pickles/test_games_ML_no_odds_56.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_56.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_56.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_60.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_60.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_60.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_61.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_61.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_61.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_62.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_62.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_62.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_63.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_63.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_63.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_63.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_63.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_63.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_64.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_64.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_64.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_64.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_64.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_64.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_66.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_66.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_66.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_66.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_66.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_66.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_68.8%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_68.8%.pkl and b/Source/Pickles/test_games_ML_no_odds_68.8%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_69.3%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_69.3%.pkl and b/Source/Pickles/test_games_ML_no_odds_69.3%.pkl differ
 
Source/Pickles/test_games_ML_no_odds_70.4%.pkl CHANGED
Binary files a/Source/Pickles/test_games_ML_no_odds_70.4%.pkl and b/Source/Pickles/test_games_ML_no_odds_70.4%.pkl differ
 
Source/Pickles/test_games_OU.pkl CHANGED
Binary files a/Source/Pickles/test_games_OU.pkl and b/Source/Pickles/test_games_OU.pkl differ
 
Source/Pickles/test_games_OU_no_odds.pkl CHANGED
Binary files a/Source/Pickles/test_games_OU_no_odds.pkl and b/Source/Pickles/test_games_OU_no_odds.pkl differ
 
Source/Pickles/the_week.pkl CHANGED
Binary files a/Source/Pickles/the_week.pkl and b/Source/Pickles/the_week.pkl differ
 
Source/Pickles/train_games_ATS_no_odds.pkl CHANGED
Binary files a/Source/Pickles/train_games_ATS_no_odds.pkl and b/Source/Pickles/train_games_ATS_no_odds.pkl differ
 
Source/Pickles/train_games_ML.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML.pkl and b/Source/Pickles/train_games_ML.pkl differ
 
Source/Pickles/train_games_ML_no_odds.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds.pkl and b/Source/Pickles/train_games_ML_no_odds.pkl differ
 
Source/Pickles/train_games_ML_no_odds_56.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_56.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_56.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_60.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_60.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_60.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_61.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_61.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_61.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_62.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_62.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_62.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_63.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_63.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_63.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_63.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_63.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_63.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_64.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_64.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_64.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_64.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_64.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_64.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_66.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_66.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_66.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_66.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_66.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_66.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_68.8%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_68.8%.pkl and b/Source/Pickles/train_games_ML_no_odds_68.8%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_69.3%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_69.3%.pkl and b/Source/Pickles/train_games_ML_no_odds_69.3%.pkl differ
 
Source/Pickles/train_games_ML_no_odds_70.4%.pkl CHANGED
Binary files a/Source/Pickles/train_games_ML_no_odds_70.4%.pkl and b/Source/Pickles/train_games_ML_no_odds_70.4%.pkl differ
 
Source/Pickles/train_games_OU.pkl CHANGED
Binary files a/Source/Pickles/train_games_OU.pkl and b/Source/Pickles/train_games_OU.pkl differ
 
Source/Pickles/train_games_OU_no_odds.pkl CHANGED
Binary files a/Source/Pickles/train_games_OU_no_odds.pkl and b/Source/Pickles/train_games_OU_no_odds.pkl differ
 
Static/Over_Under_Predictions_dark.png CHANGED
Static/Winner_Predictions_dark.png CHANGED
Templates/index.html CHANGED
@@ -1,724 +1,724 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
- <head>
5
- <link rel="shortcut icon" type="image/x-icon" href="https://images.squarespace-cdn.com/content/v1/64790f5777b5d772678cce83/6d71eaee-f825-4324-be9b-2def32469eac/favicon.ico?format=100w">
6
- <title>MARCI - NFL Betting</title>
7
- </head>
8
- <style>
9
- body {
10
- max-width: 90vw;
11
- margin: auto;
12
- background-color: black;
13
- font-family: 'Helvetica';
14
- justify-content: center;
15
- text-align: center;
16
- padding-top: 2%;
17
- padding-bottom: 5%;
18
- }
19
- p {
20
- color: #f2f2f2;
21
- }
22
- h1 {
23
- color: #f2f2f2;
24
- margin-top: 40px;
25
- margin-bottom: 10px;
26
- font-size: xxx-large;
27
- }
28
- h2 {
29
- margin-top: 0px;
30
- color: #f2f2f2;
31
- }
32
- h3 {
33
- color: #f2f2f2;
34
- margin: 0px;
35
- }
36
-
37
- table {
38
- transition: 0.3s ease;
39
- margin-top: 20px;
40
- width: 80%;
41
- border-collapse: collapse;
42
- text-align: center;
43
- }
44
- .table-div {
45
- display: flex;
46
- justify-content: center;
47
- }
48
- th, td {
49
- color: #f2f2f2;
50
- border: 1px solid black;
51
- text-align: center;
52
- padding: 8px;
53
- }
54
- th {
55
- background-color: black;
56
- }
57
- tr {
58
- background-color: black;
59
- }
60
- tr:nth-child(even) {
61
- background-color: rgb(10, 10, 5);
62
- }
63
- td img {
64
- display: block;
65
- margin: auto;
66
- }
67
- input[type="text"] {
68
- font-size: 12pt;
69
- width: 45px;
70
- height: 30px;
71
- text-align: center;
72
- background-color: transparent;
73
- border-radius: 5px;
74
- transition: 0.3s ease;
75
- color: #f2f2f2;
76
- border: none;
77
- }
78
-
79
- input[type="text"]:hover {
80
- background-color:rgb(30, 30, 30);
81
- }
82
- button {
83
- font-size: 12pt;
84
- background-color: rgb(30, 30, 30);
85
- color: #ffffff;
86
- padding: 10px 20px;
87
- border: none;
88
- border-radius: 5px;
89
- margin-top: 40px;
90
- width: 80%;
91
- transition: all 0.3s ease;
92
- }
93
- button:hover {
94
- color: rgb(0, 0, 0);
95
- background-color: rgb(255, 255, 255);
96
- cursor: pointer;
97
- }
98
- .winner-wrapper {
99
- cursor: default;
100
- position: relative;
101
- width: 100%;
102
- text-align: center;
103
- display: flex;
104
- justify-content: center;
105
- align-items: center;
106
- transition: 0.3s ease;
107
- }
108
- .winner-image {
109
- height: auto;
110
- margin: 0;
111
- transition: 0.3s ease;
112
- }
113
-
114
- .over-under-wrapper {
115
- cursor: default;
116
- position: relative;
117
- width: 100%;
118
- height: 50px;
119
- display: flex;
120
- align-items: center;
121
- justify-content: center;
122
- transition: 0.3s ease;
123
- }
124
- .over-under-text {
125
- display: inline-block;
126
- margin: 0;
127
- margin-right: 2px;
128
- font-weight: bold;
129
- }
130
- .over {
131
- color: rgb(255, 255, 255);
132
- }
133
- .under {
134
- color: rgb(255, 255, 255);
135
- }
136
- .na {
137
- color: white;
138
- }
139
-
140
- .highlight {
141
- background: rgb(30, 30, 30) !important;
142
- border: 2px solid rgb(30, 30, 30) !important;
143
- border-radius: 10px !important;
144
- }
145
-
146
- .force-repaint { transform: translateZ(0); }
147
-
148
- .hidden {
149
- opacity: 0;
150
- }
151
-
152
- .section-container {
153
- display: flex;
154
- justify-content: space-between;
155
- }
156
-
157
- .section {
158
- padding: 30px;
159
- text-align: left;
160
- border-style: solid;
161
- border-width: 1px;
162
- border-color: rgb(61, 61, 61);
163
- width: 48%;
164
- }
165
-
166
- .content {
167
- width: 100%;
168
- }
169
-
170
- .content img {
171
- width: 100%;
172
- height: auto;
173
- margin-top: 20px;
174
- margin-bottom: 20px;
175
- }
176
-
177
- .divider {
178
- border: 0;
179
- height: 1px;
180
- background: rgb(61, 61, 61);
181
- margin-top: 50px;
182
- margin-bottom: 50px;
183
- width: 80%;
184
- }
185
-
186
- .label {
187
- color: rgb(114, 114, 114);
188
- }
189
-
190
- .info {
191
- color: white;
192
- }
193
-
194
- a {
195
- color: white;
196
- }
197
-
198
- .scroll-banner {
199
- position: fixed;
200
- top: 0;
201
- left: 0;
202
- width: 100%;
203
- z-index: 999;
204
- width: 100%;
205
- display: flex;
206
- align-items: center;
207
- height: 30px;
208
- background-color: green;
209
- overflow: hidden;
210
- visibility: hidden;
211
- }
212
-
213
- .scroll-text {
214
- font-family: 'Helvetica';
215
- color: white;
216
- display: inline-block;
217
- animation: scrolling 10s linear infinite;
218
- white-space: nowrap;
219
- }
220
-
221
- @keyframes scrolling {
222
- 0% { transform: translateX(100vw); }
223
- 100% { transform: translateX(-100%); }
224
- }
225
-
226
- .emoji {
227
- margin-left: 5px;
228
- color: rgb(255, 255, 255);
229
- transition: 0.3s ease;
230
- }
231
-
232
- .spinner {
233
- margin: auto;
234
- display: block;
235
- border: 2px solid transparent;
236
- border-radius: 50%;
237
- border-top: 2px solid #6a6a6a;
238
- width: 16px;
239
- height: 16px;
240
- animation: spin 1s linear infinite;
241
- }
242
-
243
- #gradient {
244
- background: red;
245
- background: -webkit-linear-gradient(left, orange , yellow, green, cyan, blue, violet);
246
- background: -o-linear-gradient(right, orange, yellow, green, cyan, blue, violet);
247
- background: -moz-linear-gradient(right, orange, yellow, green, cyan, blue, violet);
248
- background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet);
249
- background-clip: text;
250
- -webkit-background-clip: text;
251
- -webkit-text-fill-color: transparent;
252
- font-weight: bold;
253
- }
254
-
255
- .modelDetails {
256
- width: 80%;
257
- display: inline-block;
258
- margin-bottom: 40px;
259
- }
260
-
261
- #weekSelector {
262
- transition: 0.3s ease;
263
- border-radius: 10px;
264
- padding: 5px;
265
- color: white;
266
- background: rgb(30, 30, 30) !important;
267
- font-family: Arial, Helvetica, sans-serif;
268
- }
269
- #weekSelector:hover {
270
- opacity: 0.5;
271
- }
272
-
273
- @keyframes spin {
274
- 0% {
275
- transform: rotate(0deg);
276
- }
277
- 100% {
278
- transform: rotate(360deg);
279
- }
280
- }
281
-
282
- @media screen and (max-width: 768px) {
283
- .table-div {
284
- display: block;
285
- justify-content: center;
286
- }
287
- .winner-image {
288
- margin: 0;
289
- }
290
- .emoji {
291
- margin: 0;
292
- }
293
- .table-div{
294
- overflow-x: scroll;
295
- }
296
- .divider {
297
- width: 90%;
298
- }
299
- #modelDetails {
300
- width: 90%;
301
- }
302
- .button {
303
- width: 90%;
304
- }
305
- .section-container {
306
- display: inline;
307
- }
308
- .section {
309
- padding: 15px;
310
- width: auto;
311
- }
312
- }
313
-
314
- </style>
315
-
316
- <div class="scroll-banner">
317
- <div class="scroll-text">
318
- Predictions will begin at the conclusion of Week 1. Bet at your own risk. Know your limits. And most importantly, have fun!
319
- </div>
320
- </div>
321
-
322
- <body>
323
- <h1>M A R C I</h1>
324
- <div class="info">
325
- <span class="label"><i>Moore's Algorithm for Risky Capital Investments</i></span><br><br>
326
-
327
- <span id="gradient">Remember to have fun!</span><br><br>
328
-
329
- <span class="label"><b>Record through {{ latest_game }}</b></span><br>
330
- <span class="label">Winners:</span> {{ winners_correct }}-{{winners_incorrect}}{{winners_tie}}<span class="label"> ({{ winners_return }})</span><br>
331
- <span class="label">Over/Unders:</span> {{over_unders_correct}}-{{over_unders_incorrect}}{{over_unders_push}}<span class="label"> ({{over_unders_return}})</span><br><br>
332
- </div>
333
-
334
- <select id="weekSelector">
335
- </select>
336
-
337
- <div class="table-div">
338
- <table id="gameTable">
339
- <tr>
340
- <th>Date</th>
341
- <th>Away</th>
342
- <th>Home</th>
343
- <th>O/U</th>
344
- <th>Predicted Winner</th>
345
- <th>Predicted O/U</th>
346
- </tr>
347
- </table>
348
- </div>
349
- <button id="submitButton">
350
- Predict
351
- </button>
352
-
353
- <hr class="divider">
354
-
355
- <div class="modelDetails">
356
- <h2>Model Train/Test Details</h2>
357
- <div class="section-container">
358
- <div class="section">
359
- <h3>Moneyline</h3>
360
- <div class="info"></h3><span class="label">Test Accuracy:</span> 71.4%<br></div>
361
- <div class="content">
362
- <img src="/Static/xgboost_ML_no_odds_71.4%25_dark.png" alt="Moneyline Model">
363
- <div class="info">
364
- <span class="label">Model:</span> XGBoost<br>
365
- <span class="label">Train/Test Split:</span> 1782/199<br>
366
- <span class="label">Max Depth:</span> 2<br>
367
- <span class="label">Learning Rate:</span> 0.01<br>
368
- <span class="label">Epochs:</span> 500
369
- </div>
370
- </div>
371
- </div>
372
- <div class="section">
373
- <h3>Over/Under</h3>
374
- <div class="content">
375
- <div class="info"></h3><span class="label">Test Accuracy:</span> 59.8%<br></div>
376
- <img src="/Static/xgboost_OU_no_odds_59.8%25_dark.png" alt="Over/Under Model">
377
- <div class="info">
378
- <span class="label">Model:</span> XGBoost<br>
379
- <span class="label">Train/Test Split:</span> 1782/199<br>
380
- <span class="label">Max Depth:</span> 6<br>
381
- <span class="label">Learning Rate:</span> 0.05<br>
382
- <span class="label">Epochs:</span> 300
383
- </div>
384
- </div>
385
- </div>
386
- </div>
387
- </div>
388
-
389
- <div class="modelDetails">
390
- <h2>Predictive Accuracy This Year</h2>
391
- <div class="section-container">
392
- <div class="section">
393
- <h3>Moneyline</h3>
394
- <div class="info">{{ winners_return }}.</div>
395
- <div class="content">
396
- <img src="/Static/Winner_Predictions_dark.png" alt="Moneyline Accuracy">
397
- </div>
398
- <div class="info"><span class="label">{{ winners_binom }}</span><br></div>
399
-
400
- </div>
401
- <div class="section">
402
- <h3>Over/Under</h3>
403
- <div class="info">{{ over_unders_return }}.</div>
404
- <div class="content">
405
- <img src="/Static/Over_Under_Predictions_dark.png" alt="Over/Under Model">
406
- </div>
407
- <div class="info"><span class="label">{{ over_unders_binom }}</span><br></div>
408
- </div>
409
- </div>
410
- </div>
411
-
412
- <p>πŸ€—<a href="https://huggingface.co/spaces/BraydenMoore/MARCI-NFL-Betting/tree/main">See the Code</a></p>
413
-
414
-
415
-
416
-
417
- <script>
418
- async function fetchGames(selectedWeek) {
419
- const response = await fetch(`/get_games?week=${selectedWeek}`);
420
- const pulled_games = await response.json();
421
- const table = document.getElementById('gameTable');
422
-
423
- for(let i = table.rows.length - 1; i > 0; i--) {
424
- table.deleteRow(i);
425
- }
426
-
427
- const columns = ['Date','Away Team', 'Home Team'];
428
- let lines;
429
- try {
430
- const lines_response = await fetch('/get_lines');
431
- if (!lines_response.ok) {
432
- throw new Error(`HTTP error! status: ${lines_response.status}`);
433
- }
434
- lines = await lines_response.json();
435
- }
436
- catch (error) {
437
- lines = new Array(20).fill(0);
438
- }
439
-
440
- pulled_games.forEach((game, index) => {
441
- const row = table.insertRow(-1);
442
-
443
- columns.forEach((column) => {
444
- const cell = row.insertCell(-1);
445
- if (column === 'Away Team' || column === 'Home Team') {
446
- const img = document.createElement('img');
447
- img.src = `/Static/${game[column]}.webp`;
448
- img.alt = game[column];
449
- img.width = 50;
450
- cell.appendChild(img);
451
- } else {
452
- cell.textContent = game[column];
453
- cell.style.color = "rgb(114, 114, 114)";
454
- }
455
- });
456
-
457
- for (let i = 0; i < 3; i++) {
458
- const cell = row.insertCell(-1);
459
- if (i<1) {
460
- const input = document.createElement('input');
461
- input.type = 'text';
462
- input.value = lines[index];
463
- cell.appendChild(input);
464
- }
465
- }
466
- });
467
- }
468
-
469
-
470
- function submitData() {
471
- const predictButton = document.getElementById('submitButton');
472
-
473
- const table = document.getElementById('gameTable');
474
- const rows = table.querySelectorAll('tr');
475
- const games = [];
476
-
477
- rows.forEach((row, index) => {
478
- if (index === 0) return;
479
-
480
- const winnerCell = row.cells[row.cells.length - 2];
481
- const overUnderCell = row.cells[row.cells.length - 1];
482
- const spinnerDiv = document.createElement('div');
483
- spinnerDiv.className = 'spinner';
484
- winnerCell.innerHTML = '';
485
- overUnderCell.innerHTML = '';
486
- winnerCell.appendChild(spinnerDiv);
487
- overUnderCell.appendChild(spinnerDiv.cloneNode(true));
488
-
489
- const cells = row.querySelectorAll('td');
490
- const game = {};
491
-
492
- game.Date = cells[0].textContent;
493
- game.AwayTeam = cells[1].querySelector('img').alt;
494
- game.HomeTeam = cells[2].querySelector('img').alt;
495
- game.OverUnderLine = cells[3].querySelector('input').value;
496
- game.rowIndex = index - 1;
497
- games.push(game);
498
- });
499
-
500
-
501
- fetch('/submit_games', {
502
- method: 'POST',
503
- headers: {
504
- 'Content-Type': 'application/json',
505
- },
506
- body: JSON.stringify(games),
507
- })
508
- .then(response => response.json())
509
- .then(data => {
510
- if (data.moneylines && data.over_unders) {
511
- const table = document.getElementById('gameTable');
512
- const rows = table.querySelectorAll('tr');
513
-
514
- data.moneylines.forEach((moneyline, index) => {
515
- const row = rows[parseInt(moneyline.rowIndex) + 1];
516
-
517
- const winnerCell = row.cells[row.cells.length - 2];
518
- winnerCell.removeChild(winnerCell.querySelector('.spinner'));
519
- winnerCell.innerHTML = '';
520
-
521
- const wrapperDiv = document.createElement('div');
522
- wrapperDiv.className = 'winner-wrapper';
523
- if (moneyline.Probabilities[0] > 0.6){
524
- wrapperDiv.classList.add("highlight");
525
- }
526
- else {
527
- wrapperDiv.style.opacity = "0.5";
528
- }
529
-
530
- const winnerImg = document.createElement('img');
531
- winnerImg.src = `/Static/${moneyline.Winner}.webp`;
532
- winnerImg.alt = moneyline.Winner;
533
- winnerImg.width = 50;
534
- winnerImg.className = 'winner-image hidden';
535
- wrapperDiv.appendChild(winnerImg);
536
-
537
- const winnerEmojiDiv = document.createElement('div');
538
- winnerEmojiDiv.className = 'emoji';
539
-
540
- wrapperDiv.dataset.proba = Math.floor(moneyline.Probabilities[0] * 100).toFixed(0);
541
- if (moneyline.Winner[0] === moneyline.Result) {
542
- winnerEmojiDiv.textContent = 'βœ…';
543
- }
544
- else if (moneyline.Result === 'Tie') {
545
- winnerEmojiDiv.textContent = 'πŸ”΅';
546
- }
547
- else {
548
- winnerEmojiDiv.textContent = '❌';
549
- }
550
- if (moneyline.Result === 'N/A') {
551
- winnerEmojiDiv.textContent = `(${wrapperDiv.dataset.proba}%)`;
552
- }
553
- wrapperDiv.appendChild(winnerEmojiDiv);
554
-
555
- setTimeout(() => {
556
- winnerImg.classList.remove('hidden');
557
- }, 10);
558
-
559
- winnerCell.appendChild(wrapperDiv);
560
-
561
- const overUnderCell = row.cells[row.cells.length - 1];
562
- overUnderCell.removeChild(overUnderCell.querySelector('.spinner'));
563
- overUnderCell.innerHTML = '';
564
-
565
- const overUnderDiv = document.createElement('div');
566
- overUnderDiv.className = 'over-under-wrapper hidden';
567
- if (data.over_unders[index]['Probability'][0] > 0.6){
568
- overUnderDiv.classList.add("highlight");
569
- }
570
- else {
571
- overUnderDiv.style.opacity = "0.5";
572
- }
573
-
574
- const textDiv = document.createElement('div');
575
- textDiv.className = 'over-under-text';
576
- textDiv.textContent = data.over_unders[index]['Over/Under'];
577
- if (textDiv.textContent === 'Over') {
578
- overUnderDiv.className += ' over';
579
- } else if (textDiv.textContent === 'Under') {
580
- overUnderDiv.className += ' under';
581
- } else {
582
- overUnderDiv.className += ' na';
583
- }
584
-
585
- overUnderDiv.appendChild(textDiv);
586
-
587
- const overEmojiDiv = document.createElement('div');
588
- overEmojiDiv.className = 'emoji';
589
-
590
- overUnderDiv.dataset.proba = Math.floor(data.over_unders[index]['Probability'][0] * 100).toFixed(0);
591
- if (data.over_unders[index]['Over/Under'][0] === data.over_unders[index]['Result']) {
592
- overEmojiDiv.textContent = 'βœ…';
593
- }
594
- else if (data.over_unders[index]['Result'] === 'Push') {
595
- overEmojiDiv.textContent = 'πŸ”΅';
596
- }
597
- else {
598
- overEmojiDiv.textContent = '❌';
599
- }
600
- if (data.over_unders[index]['Result'] === 'N/A') {
601
- overEmojiDiv.textContent = `(${overUnderDiv.dataset.proba}%)`;
602
- }
603
- overUnderDiv.appendChild(overEmojiDiv);
604
-
605
- setTimeout(() => {
606
- overUnderDiv.classList.remove('hidden');
607
- }, 10);
608
-
609
- overUnderCell.appendChild(overUnderDiv);
610
-
611
- showProbabilityOnHover(wrapperDiv);
612
- showProbabilityOnHover(overUnderDiv);
613
-
614
- });
615
- }
616
- });
617
-
618
- }
619
-
620
- //Hover listener
621
- function showProbabilityOnHover(div) {
622
- let previousValue;
623
- let divText = div.children[1];
624
- let eventProcessed = false;
625
-
626
- function handleEnter() {
627
- if (eventProcessed) return; // Skip if an event has already been processed
628
-
629
- eventProcessed = true;
630
-
631
- if (divText.textContent !== `(${div.dataset.proba}%)`) {
632
- divText.style.opacity = 0;
633
-
634
- setTimeout(() => {
635
- previousValue = divText.textContent;
636
- divText.textContent = `(${div.dataset.proba}%)`;
637
- divText.style.opacity = 1;
638
- }, 300);
639
-
640
- setTimeout(() => {
641
- divText.style.opacity = 0;
642
- setTimeout(() => {
643
- divText.textContent = previousValue;
644
- divText.style.opacity = 1;
645
- eventProcessed = false; // Reset the flag
646
- }, 300);
647
- }, 1000);
648
- }
649
- }
650
-
651
- // For desktop
652
- div.addEventListener('mouseenter', handleEnter);
653
- // For mobile
654
- div.addEventListener('touchstart', handleEnter);
655
- }
656
-
657
- // Populate dropdown
658
- let selectedWeek;
659
- async function populateDropdown() {
660
- const weekSelector = document.getElementById('weekSelector');
661
- weekSelector.innerHTML = "";
662
-
663
- const response = await fetch('/get_weeks');
664
- const data = await response.json();
665
-
666
- data.forEach((week, index) => {
667
- const option = document.createElement('option');
668
- option.value = week;
669
- option.text = `Week ${week}`;
670
- weekSelector.appendChild(option);
671
-
672
- if (index === 0) {
673
- selectedWeek = week;
674
- }
675
- });
676
- }
677
-
678
-
679
- // Get new games when new week selected
680
- document.getElementById('weekSelector').addEventListener('change', function(event) {
681
- selectedWeek = event.target.value;
682
- getNew();
683
- });
684
-
685
-
686
- // Initial load
687
- function loadThings() {
688
- populateDropdown()
689
- .then(() => fetchGames(selectedWeek))
690
- .then(() => submitData())
691
- .catch(error => console.error(error));
692
- }
693
-
694
- // Get new
695
- async function getNew() {
696
- const table = document.getElementById('gameTable');
697
- table.style.opacity = "0.5";
698
-
699
- try {
700
- await fetchGames(selectedWeek);
701
- await submitData();
702
- table.style.opacity = "1";
703
- } catch (error) {
704
- console.error(error);
705
- }
706
- }
707
-
708
-
709
- // Submit on click, enter, and pageload
710
- loadThings();
711
-
712
- document.getElementById('submitButton').addEventListener('click', submitData);
713
-
714
- document.addEventListener('keydown', function(event) {
715
- if (event.keyCode === 13) {
716
- submitData();
717
- }
718
- });
719
-
720
-
721
- </script>
722
-
723
- </body>
724
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <head>
5
+ <link rel="shortcut icon" type="image/x-icon" href="https://images.squarespace-cdn.com/content/v1/64790f5777b5d772678cce83/6d71eaee-f825-4324-be9b-2def32469eac/favicon.ico?format=100w">
6
+ <title>MARCI - NFL Betting</title>
7
+ </head>
8
+ <style>
9
+ body {
10
+ max-width: 90vw;
11
+ margin: auto;
12
+ background-color: black;
13
+ font-family: 'Helvetica';
14
+ justify-content: center;
15
+ text-align: center;
16
+ padding-top: 2%;
17
+ padding-bottom: 5%;
18
+ }
19
+ p {
20
+ color: #f2f2f2;
21
+ }
22
+ h1 {
23
+ color: #f2f2f2;
24
+ margin-top: 40px;
25
+ margin-bottom: 10px;
26
+ font-size: xxx-large;
27
+ }
28
+ h2 {
29
+ margin-top: 0px;
30
+ color: #f2f2f2;
31
+ }
32
+ h3 {
33
+ color: #f2f2f2;
34
+ margin: 0px;
35
+ }
36
+
37
+ table {
38
+ transition: 0.3s ease;
39
+ margin-top: 20px;
40
+ width: 80%;
41
+ border-collapse: collapse;
42
+ text-align: center;
43
+ }
44
+ .table-div {
45
+ display: flex;
46
+ justify-content: center;
47
+ }
48
+ th, td {
49
+ color: #f2f2f2;
50
+ border: 1px solid black;
51
+ text-align: center;
52
+ padding: 8px;
53
+ }
54
+ th {
55
+ background-color: black;
56
+ }
57
+ tr {
58
+ background-color: black;
59
+ }
60
+ tr:nth-child(even) {
61
+ background-color: rgb(10, 10, 5);
62
+ }
63
+ td img {
64
+ display: block;
65
+ margin: auto;
66
+ }
67
+ input[type="text"] {
68
+ font-size: 12pt;
69
+ width: 45px;
70
+ height: 30px;
71
+ text-align: center;
72
+ background-color: transparent;
73
+ border-radius: 5px;
74
+ transition: 0.3s ease;
75
+ color: #f2f2f2;
76
+ border: none;
77
+ }
78
+
79
+ input[type="text"]:hover {
80
+ background-color:rgb(30, 30, 30);
81
+ }
82
+ button {
83
+ font-size: 12pt;
84
+ background-color: rgb(30, 30, 30);
85
+ color: #ffffff;
86
+ padding: 10px 20px;
87
+ border: none;
88
+ border-radius: 5px;
89
+ margin-top: 40px;
90
+ width: 80%;
91
+ transition: all 0.3s ease;
92
+ }
93
+ button:hover {
94
+ color: rgb(0, 0, 0);
95
+ background-color: rgb(255, 255, 255);
96
+ cursor: pointer;
97
+ }
98
+ .winner-wrapper {
99
+ cursor: default;
100
+ position: relative;
101
+ width: 100%;
102
+ text-align: center;
103
+ display: flex;
104
+ justify-content: center;
105
+ align-items: center;
106
+ transition: 0.3s ease;
107
+ }
108
+ .winner-image {
109
+ height: auto;
110
+ margin: 0;
111
+ transition: 0.3s ease;
112
+ }
113
+
114
+ .over-under-wrapper {
115
+ cursor: default;
116
+ position: relative;
117
+ width: 100%;
118
+ height: 50px;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ transition: 0.3s ease;
123
+ }
124
+ .over-under-text {
125
+ display: inline-block;
126
+ margin: 0;
127
+ margin-right: 2px;
128
+ font-weight: bold;
129
+ }
130
+ .over {
131
+ color: rgb(255, 255, 255);
132
+ }
133
+ .under {
134
+ color: rgb(255, 255, 255);
135
+ }
136
+ .na {
137
+ color: white;
138
+ }
139
+
140
+ .highlight {
141
+ background: rgb(30, 30, 30) !important;
142
+ border: 2px solid rgb(30, 30, 30) !important;
143
+ border-radius: 10px !important;
144
+ }
145
+
146
+ .force-repaint { transform: translateZ(0); }
147
+
148
+ .hidden {
149
+ opacity: 0;
150
+ }
151
+
152
+ .section-container {
153
+ display: flex;
154
+ justify-content: space-between;
155
+ }
156
+
157
+ .section {
158
+ padding: 30px;
159
+ text-align: left;
160
+ border-style: solid;
161
+ border-width: 1px;
162
+ border-color: rgb(61, 61, 61);
163
+ width: 48%;
164
+ }
165
+
166
+ .content {
167
+ width: 100%;
168
+ }
169
+
170
+ .content img {
171
+ width: 100%;
172
+ height: auto;
173
+ margin-top: 20px;
174
+ margin-bottom: 20px;
175
+ }
176
+
177
+ .divider {
178
+ border: 0;
179
+ height: 1px;
180
+ background: rgb(61, 61, 61);
181
+ margin-top: 50px;
182
+ margin-bottom: 50px;
183
+ width: 80%;
184
+ }
185
+
186
+ .label {
187
+ color: rgb(114, 114, 114);
188
+ }
189
+
190
+ .info {
191
+ color: white;
192
+ }
193
+
194
+ a {
195
+ color: white;
196
+ }
197
+
198
+ .scroll-banner {
199
+ position: fixed;
200
+ top: 0;
201
+ left: 0;
202
+ width: 100%;
203
+ z-index: 999;
204
+ width: 100%;
205
+ display: flex;
206
+ align-items: center;
207
+ height: 30px;
208
+ background-color: green;
209
+ overflow: hidden;
210
+ visibility: hidden;
211
+ }
212
+
213
+ .scroll-text {
214
+ font-family: 'Helvetica';
215
+ color: white;
216
+ display: inline-block;
217
+ animation: scrolling 10s linear infinite;
218
+ white-space: nowrap;
219
+ }
220
+
221
+ @keyframes scrolling {
222
+ 0% { transform: translateX(100vw); }
223
+ 100% { transform: translateX(-100%); }
224
+ }
225
+
226
+ .emoji {
227
+ margin-left: 5px;
228
+ color: rgb(255, 255, 255);
229
+ transition: 0.3s ease;
230
+ }
231
+
232
+ .spinner {
233
+ margin: auto;
234
+ display: block;
235
+ border: 2px solid transparent;
236
+ border-radius: 50%;
237
+ border-top: 2px solid #6a6a6a;
238
+ width: 16px;
239
+ height: 16px;
240
+ animation: spin 1s linear infinite;
241
+ }
242
+
243
+ #gradient {
244
+ background: red;
245
+ background: -webkit-linear-gradient(left, orange , yellow, green, cyan, blue, violet);
246
+ background: -o-linear-gradient(right, orange, yellow, green, cyan, blue, violet);
247
+ background: -moz-linear-gradient(right, orange, yellow, green, cyan, blue, violet);
248
+ background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet);
249
+ background-clip: text;
250
+ -webkit-background-clip: text;
251
+ -webkit-text-fill-color: transparent;
252
+ font-weight: bold;
253
+ }
254
+
255
+ .modelDetails {
256
+ width: 80%;
257
+ display: inline-block;
258
+ margin-bottom: 40px;
259
+ }
260
+
261
+ #weekSelector {
262
+ transition: 0.3s ease;
263
+ border-radius: 10px;
264
+ padding: 5px;
265
+ color: white;
266
+ background: rgb(30, 30, 30) !important;
267
+ font-family: Arial, Helvetica, sans-serif;
268
+ }
269
+ #weekSelector:hover {
270
+ opacity: 0.5;
271
+ }
272
+
273
+ @keyframes spin {
274
+ 0% {
275
+ transform: rotate(0deg);
276
+ }
277
+ 100% {
278
+ transform: rotate(360deg);
279
+ }
280
+ }
281
+
282
+ @media screen and (max-width: 768px) {
283
+ .table-div {
284
+ display: block;
285
+ justify-content: center;
286
+ }
287
+ .winner-image {
288
+ margin: 0;
289
+ }
290
+ .emoji {
291
+ margin: 0;
292
+ }
293
+ .table-div{
294
+ overflow-x: scroll;
295
+ }
296
+ .divider {
297
+ width: 90%;
298
+ }
299
+ #modelDetails {
300
+ width: 90%;
301
+ }
302
+ .button {
303
+ width: 90%;
304
+ }
305
+ .section-container {
306
+ display: inline;
307
+ }
308
+ .section {
309
+ padding: 15px;
310
+ width: auto;
311
+ }
312
+ }
313
+
314
+ </style>
315
+
316
+ <div class="scroll-banner">
317
+ <div class="scroll-text">
318
+ Predictions will begin at the conclusion of Week 1. Bet at your own risk. Know your limits. And most importantly, have fun!
319
+ </div>
320
+ </div>
321
+
322
+ <body>
323
+ <h1>M A R C I</h1>
324
+ <div class="info">
325
+ <span class="label"><i>Moore's Algorithm for Risky Capital Investments</i></span><br><br>
326
+
327
+ <span id="gradient">Remember to have fun!</span><br><br>
328
+
329
+ <span class="label"><b>Record through {{ latest_game }}</b></span><br>
330
+ <span class="label">Winners:</span> {{ winners_correct }}-{{winners_incorrect}}{{winners_tie}}<span class="label"> ({{ winners_return }})</span><br>
331
+ <span class="label">Over/Unders:</span> {{over_unders_correct}}-{{over_unders_incorrect}}{{over_unders_push}}<span class="label"> ({{over_unders_return}})</span><br><br>
332
+ </div>
333
+
334
+ <select id="weekSelector">
335
+ </select>
336
+
337
+ <div class="table-div">
338
+ <table id="gameTable">
339
+ <tr>
340
+ <th>Date</th>
341
+ <th>Away</th>
342
+ <th>Home</th>
343
+ <th>O/U</th>
344
+ <th>Predicted Winner</th>
345
+ <th>Predicted O/U</th>
346
+ </tr>
347
+ </table>
348
+ </div>
349
+ <button id="submitButton">
350
+ Predict
351
+ </button>
352
+
353
+ <hr class="divider">
354
+
355
+ <div class="modelDetails">
356
+ <h2>Model Train/Test Details</h2>
357
+ <div class="section-container">
358
+ <div class="section">
359
+ <h3>Moneyline</h3>
360
+ <div class="info"></h3><span class="label">Test Accuracy:</span> 71.4%<br></div>
361
+ <div class="content">
362
+ <img src="/Static/xgboost_ML_no_odds_71.4%25_dark.png" alt="Moneyline Model">
363
+ <div class="info">
364
+ <span class="label">Model:</span> XGBoost<br>
365
+ <span class="label">Train/Test Split:</span> 1782/199<br>
366
+ <span class="label">Max Depth:</span> 2<br>
367
+ <span class="label">Learning Rate:</span> 0.01<br>
368
+ <span class="label">Epochs:</span> 500
369
+ </div>
370
+ </div>
371
+ </div>
372
+ <div class="section">
373
+ <h3>Over/Under</h3>
374
+ <div class="content">
375
+ <div class="info"></h3><span class="label">Test Accuracy:</span> 59.8%<br></div>
376
+ <img src="/Static/xgboost_OU_no_odds_59.8%25_dark.png" alt="Over/Under Model">
377
+ <div class="info">
378
+ <span class="label">Model:</span> XGBoost<br>
379
+ <span class="label">Train/Test Split:</span> 1782/199<br>
380
+ <span class="label">Max Depth:</span> 6<br>
381
+ <span class="label">Learning Rate:</span> 0.05<br>
382
+ <span class="label">Epochs:</span> 300
383
+ </div>
384
+ </div>
385
+ </div>
386
+ </div>
387
+ </div>
388
+
389
+ <div class="modelDetails">
390
+ <h2>Predictive Accuracy This Year</h2>
391
+ <div class="section-container">
392
+ <div class="section">
393
+ <h3>Moneyline</h3>
394
+ <div class="info">{{ winners_return }}.</div>
395
+ <div class="content">
396
+ <img src="/Static/Winner_Predictions_dark.png" alt="Moneyline Accuracy">
397
+ </div>
398
+ <div class="info"><span class="label">{{ winners_binom }}</span><br></div>
399
+
400
+ </div>
401
+ <div class="section">
402
+ <h3>Over/Under</h3>
403
+ <div class="info">{{ over_unders_return }}.</div>
404
+ <div class="content">
405
+ <img src="/Static/Over_Under_Predictions_dark.png" alt="Over/Under Model">
406
+ </div>
407
+ <div class="info"><span class="label">{{ over_unders_binom }}</span><br></div>
408
+ </div>
409
+ </div>
410
+ </div>
411
+
412
+ <p>πŸ€—<a href="https://huggingface.co/spaces/BraydenMoore/MARCI-NFL-Betting/tree/main">See the Code</a></p>
413
+
414
+
415
+
416
+
417
+ <script>
418
+ async function fetchGames(selectedWeek) {
419
+ const response = await fetch(`/get_games?week=${selectedWeek}`);
420
+ const pulled_games = await response.json();
421
+ const table = document.getElementById('gameTable');
422
+
423
+ for(let i = table.rows.length - 1; i > 0; i--) {
424
+ table.deleteRow(i);
425
+ }
426
+
427
+ const columns = ['Date','Away Team', 'Home Team'];
428
+ let lines;
429
+ try {
430
+ const lines_response = await fetch('/get_lines');
431
+ if (!lines_response.ok) {
432
+ throw new Error(`HTTP error! status: ${lines_response.status}`);
433
+ }
434
+ lines = await lines_response.json();
435
+ }
436
+ catch (error) {
437
+ lines = new Array(20).fill(0);
438
+ }
439
+
440
+ pulled_games.forEach((game, index) => {
441
+ const row = table.insertRow(-1);
442
+
443
+ columns.forEach((column) => {
444
+ const cell = row.insertCell(-1);
445
+ if (column === 'Away Team' || column === 'Home Team') {
446
+ const img = document.createElement('img');
447
+ img.src = `/Static/${game[column]}.webp`;
448
+ img.alt = game[column];
449
+ img.width = 50;
450
+ cell.appendChild(img);
451
+ } else {
452
+ cell.textContent = game[column];
453
+ cell.style.color = "rgb(114, 114, 114)";
454
+ }
455
+ });
456
+
457
+ for (let i = 0; i < 3; i++) {
458
+ const cell = row.insertCell(-1);
459
+ if (i<1) {
460
+ const input = document.createElement('input');
461
+ input.type = 'text';
462
+ input.value = lines[index];
463
+ cell.appendChild(input);
464
+ }
465
+ }
466
+ });
467
+ }
468
+
469
+
470
+ function submitData() {
471
+ const predictButton = document.getElementById('submitButton');
472
+
473
+ const table = document.getElementById('gameTable');
474
+ const rows = table.querySelectorAll('tr');
475
+ const games = [];
476
+
477
+ rows.forEach((row, index) => {
478
+ if (index === 0) return;
479
+
480
+ const winnerCell = row.cells[row.cells.length - 2];
481
+ const overUnderCell = row.cells[row.cells.length - 1];
482
+ const spinnerDiv = document.createElement('div');
483
+ spinnerDiv.className = 'spinner';
484
+ winnerCell.innerHTML = '';
485
+ overUnderCell.innerHTML = '';
486
+ winnerCell.appendChild(spinnerDiv);
487
+ overUnderCell.appendChild(spinnerDiv.cloneNode(true));
488
+
489
+ const cells = row.querySelectorAll('td');
490
+ const game = {};
491
+
492
+ game.Date = cells[0].textContent;
493
+ game.AwayTeam = cells[1].querySelector('img').alt;
494
+ game.HomeTeam = cells[2].querySelector('img').alt;
495
+ game.OverUnderLine = cells[3].querySelector('input').value;
496
+ game.rowIndex = index - 1;
497
+ games.push(game);
498
+ });
499
+
500
+
501
+ fetch('/submit_games', {
502
+ method: 'POST',
503
+ headers: {
504
+ 'Content-Type': 'application/json',
505
+ },
506
+ body: JSON.stringify(games),
507
+ })
508
+ .then(response => response.json())
509
+ .then(data => {
510
+ if (data.moneylines && data.over_unders) {
511
+ const table = document.getElementById('gameTable');
512
+ const rows = table.querySelectorAll('tr');
513
+
514
+ data.moneylines.forEach((moneyline, index) => {
515
+ const row = rows[parseInt(moneyline.rowIndex) + 1];
516
+
517
+ const winnerCell = row.cells[row.cells.length - 2];
518
+ winnerCell.removeChild(winnerCell.querySelector('.spinner'));
519
+ winnerCell.innerHTML = '';
520
+
521
+ const wrapperDiv = document.createElement('div');
522
+ wrapperDiv.className = 'winner-wrapper';
523
+ if (moneyline.Probabilities[0] > 0.6){
524
+ wrapperDiv.classList.add("highlight");
525
+ }
526
+ else {
527
+ wrapperDiv.style.opacity = "0.5";
528
+ }
529
+
530
+ const winnerImg = document.createElement('img');
531
+ winnerImg.src = `/Static/${moneyline.Winner}.webp`;
532
+ winnerImg.alt = moneyline.Winner;
533
+ winnerImg.width = 50;
534
+ winnerImg.className = 'winner-image hidden';
535
+ wrapperDiv.appendChild(winnerImg);
536
+
537
+ const winnerEmojiDiv = document.createElement('div');
538
+ winnerEmojiDiv.className = 'emoji';
539
+
540
+ wrapperDiv.dataset.proba = Math.floor(moneyline.Probabilities[0] * 100).toFixed(0);
541
+ if (moneyline.Winner[0] === moneyline.Result) {
542
+ winnerEmojiDiv.textContent = 'βœ…';
543
+ }
544
+ else if (moneyline.Result === 'Tie') {
545
+ winnerEmojiDiv.textContent = 'πŸ”΅';
546
+ }
547
+ else {
548
+ winnerEmojiDiv.textContent = '❌';
549
+ }
550
+ if (moneyline.Result === 'N/A') {
551
+ winnerEmojiDiv.textContent = `(${wrapperDiv.dataset.proba}%)`;
552
+ }
553
+ wrapperDiv.appendChild(winnerEmojiDiv);
554
+
555
+ setTimeout(() => {
556
+ winnerImg.classList.remove('hidden');
557
+ }, 10);
558
+
559
+ winnerCell.appendChild(wrapperDiv);
560
+
561
+ const overUnderCell = row.cells[row.cells.length - 1];
562
+ overUnderCell.removeChild(overUnderCell.querySelector('.spinner'));
563
+ overUnderCell.innerHTML = '';
564
+
565
+ const overUnderDiv = document.createElement('div');
566
+ overUnderDiv.className = 'over-under-wrapper hidden';
567
+ if (data.over_unders[index]['Probability'][0] > 0.6){
568
+ overUnderDiv.classList.add("highlight");
569
+ }
570
+ else {
571
+ overUnderDiv.style.opacity = "0.5";
572
+ }
573
+
574
+ const textDiv = document.createElement('div');
575
+ textDiv.className = 'over-under-text';
576
+ textDiv.textContent = data.over_unders[index]['Over/Under'];
577
+ if (textDiv.textContent === 'Over') {
578
+ overUnderDiv.className += ' over';
579
+ } else if (textDiv.textContent === 'Under') {
580
+ overUnderDiv.className += ' under';
581
+ } else {
582
+ overUnderDiv.className += ' na';
583
+ }
584
+
585
+ overUnderDiv.appendChild(textDiv);
586
+
587
+ const overEmojiDiv = document.createElement('div');
588
+ overEmojiDiv.className = 'emoji';
589
+
590
+ overUnderDiv.dataset.proba = Math.floor(data.over_unders[index]['Probability'][0] * 100).toFixed(0);
591
+ if (data.over_unders[index]['Over/Under'][0] === data.over_unders[index]['Result']) {
592
+ overEmojiDiv.textContent = 'βœ…';
593
+ }
594
+ else if (data.over_unders[index]['Result'] === 'Push') {
595
+ overEmojiDiv.textContent = 'πŸ”΅';
596
+ }
597
+ else {
598
+ overEmojiDiv.textContent = '❌';
599
+ }
600
+ if (data.over_unders[index]['Result'] === 'N/A') {
601
+ overEmojiDiv.textContent = `(${overUnderDiv.dataset.proba}%)`;
602
+ }
603
+ overUnderDiv.appendChild(overEmojiDiv);
604
+
605
+ setTimeout(() => {
606
+ overUnderDiv.classList.remove('hidden');
607
+ }, 10);
608
+
609
+ overUnderCell.appendChild(overUnderDiv);
610
+
611
+ showProbabilityOnHover(wrapperDiv);
612
+ showProbabilityOnHover(overUnderDiv);
613
+
614
+ });
615
+ }
616
+ });
617
+
618
+ }
619
+
620
+ //Hover listener
621
+ function showProbabilityOnHover(div) {
622
+ let previousValue;
623
+ let divText = div.children[1];
624
+ let eventProcessed = false;
625
+
626
+ function handleEnter() {
627
+ if (eventProcessed) return; // Skip if an event has already been processed
628
+
629
+ eventProcessed = true;
630
+
631
+ if (divText.textContent !== `(${div.dataset.proba}%)`) {
632
+ divText.style.opacity = 0;
633
+
634
+ setTimeout(() => {
635
+ previousValue = divText.textContent;
636
+ divText.textContent = `(${div.dataset.proba}%)`;
637
+ divText.style.opacity = 1;
638
+ }, 300);
639
+
640
+ setTimeout(() => {
641
+ divText.style.opacity = 0;
642
+ setTimeout(() => {
643
+ divText.textContent = previousValue;
644
+ divText.style.opacity = 1;
645
+ eventProcessed = false; // Reset the flag
646
+ }, 300);
647
+ }, 1000);
648
+ }
649
+ }
650
+
651
+ // For desktop
652
+ div.addEventListener('mouseenter', handleEnter);
653
+ // For mobile
654
+ div.addEventListener('touchstart', handleEnter);
655
+ }
656
+
657
+ // Populate dropdown
658
+ let selectedWeek;
659
+ async function populateDropdown() {
660
+ const weekSelector = document.getElementById('weekSelector');
661
+ weekSelector.innerHTML = "";
662
+
663
+ const response = await fetch('/get_weeks');
664
+ const data = await response.json();
665
+
666
+ data.forEach((week, index) => {
667
+ const option = document.createElement('option');
668
+ option.value = week;
669
+ option.text = `Week ${week}`;
670
+ weekSelector.appendChild(option);
671
+
672
+ if (index === 0) {
673
+ selectedWeek = week;
674
+ }
675
+ });
676
+ }
677
+
678
+
679
+ // Get new games when new week selected
680
+ document.getElementById('weekSelector').addEventListener('change', function(event) {
681
+ selectedWeek = event.target.value;
682
+ getNew();
683
+ });
684
+
685
+
686
+ // Initial load
687
+ function loadThings() {
688
+ populateDropdown()
689
+ .then(() => fetchGames(selectedWeek))
690
+ .then(() => submitData())
691
+ .catch(error => console.error(error));
692
+ }
693
+
694
+ // Get new
695
+ async function getNew() {
696
+ const table = document.getElementById('gameTable');
697
+ table.style.opacity = "0.5";
698
+
699
+ try {
700
+ await fetchGames(selectedWeek);
701
+ await submitData();
702
+ table.style.opacity = "1";
703
+ } catch (error) {
704
+ console.error(error);
705
+ }
706
+ }
707
+
708
+
709
+ // Submit on click, enter, and pageload
710
+ loadThings();
711
+
712
+ document.getElementById('submitButton').addEventListener('click', submitData);
713
+
714
+ document.addEventListener('keydown', function(event) {
715
+ if (event.keyCode === 13) {
716
+ submitData();
717
+ }
718
+ });
719
+
720
+
721
+ </script>
722
+
723
+ </body>
724
+ </html>