BraydenMoore commited on
Commit
1a89c67
1 Parent(s): 623a8f8

Update site title

Browse files
Source/Data/gbg_and_odds_this_year.csv CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:2ecdf4a1128d584ae28bc98c403493a32bc41583a8519f1fba4266ded10a401e
3
  size 27668
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8cf6bbbabaf4d15ab0c59ff18348c88bbcf67b8eac7161b662b7e77cd6fcb4f4
3
  size 27668
Source/Data/gbg_this_year.csv CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:11843b13ce21805c21f2e1f93a2a95c071aadf6d144e35708cc306f867cf1908
3
  size 24329
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d085f5ecdd8cf42ee64b7ae6d2d3221ca0402864bddbc02c89f23edf2ed9389
3
  size 24329
Source/Data/lines.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 43,
41
+ 53.5,
42
+ 45.5,
43
+ 46,
44
+ 41,
45
+ 42.5,
46
+ 46.5,
47
+ 40.5,
48
+ 43.5,
49
+ 41,
50
+ 48,
51
+ 43,
52
+ 44.5,
53
+ 41.5,
54
+ 47
55
+ ]
56
+ }
Source/Predict/__pycache__/predict.cpython-311.pyc CHANGED
Binary files a/Source/Predict/__pycache__/predict.cpython-311.pyc and b/Source/Predict/__pycache__/predict.cpython-311.pyc differ
 
Source/Predict/predict.py CHANGED
@@ -7,6 +7,7 @@ import requests
7
  from bs4 import BeautifulSoup
8
  import warnings
9
  warnings.filterwarnings("ignore")
 
10
 
11
  # set dirs for other files
12
  current_directory = os.path.dirname(os.path.abspath(__file__))
@@ -30,6 +31,20 @@ file_path = os.path.join(pickle_directory, 'team_abbreviation_to_name.pkl')
30
  with open(file_path, 'rb') as f:
31
  team_abbreviation_to_name = pkl.load(f)
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  def get_week():
34
  headers = {
35
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
@@ -47,7 +62,6 @@ def get_week():
47
  h2_tags = soup.find_all('h2')
48
  year = h2_tags[0].getText().split(' ')[0]
49
  week = h2_tags[0].getText().split(' ')[-1]
50
- print(week)
51
  return int(week), int(year)
52
 
53
 
@@ -103,13 +117,8 @@ def predict(home,away,season,week,total):
103
  matrix = xgb.DMatrix(data.astype(float).values)
104
 
105
  # create game id
106
- game_id = str(season) + '_0' + str(week) + '_' + away_abbrev + '_' + home_abbrev
107
-
108
- # moneyline
109
- model = 'xgboost_ML_no_odds_71.4%'
110
- file_path = os.path.join(model_directory, f'{model}.json')
111
- xgb_ml = xgb.Booster()
112
- xgb_ml.load_model(file_path)
113
 
114
  try:
115
  moneyline_result = results.loc[results['game_id']==game_id, 'winner'].item()
@@ -126,12 +135,6 @@ def predict(home,away,season,week,total):
126
  moneyline = {'Winner': 'NA',
127
  'Probabilities':['N/A'],
128
  'Result': moneyline_result}
129
-
130
- # over/under
131
- model = 'xgboost_OU_no_odds_59.8%'
132
- file_path = os.path.join(model_directory, f'{model}.json')
133
- xgb_ou = xgb.Booster()
134
- xgb_ou.load_model(file_path)
135
 
136
  try:
137
  result = results.loc[results['game_id']==game_id, 'total'].item()
 
7
  from bs4 import BeautifulSoup
8
  import warnings
9
  warnings.filterwarnings("ignore")
10
+ from datetime import datetime
11
 
12
  # set dirs for other files
13
  current_directory = os.path.dirname(os.path.abspath(__file__))
 
31
  with open(file_path, 'rb') as f:
32
  team_abbreviation_to_name = pkl.load(f)
33
 
34
+ # load models
35
+ # moneyline
36
+ model = 'xgboost_ML_no_odds_71.4%'
37
+ file_path = os.path.join(model_directory, f'{model}.json')
38
+ xgb_ml = xgb.Booster()
39
+ xgb_ml.load_model(file_path)
40
+
41
+ # over/under
42
+ model = 'xgboost_OU_no_odds_59.8%'
43
+ file_path = os.path.join(model_directory, f'{model}.json')
44
+ xgb_ou = xgb.Booster()
45
+ xgb_ou.load_model(file_path)
46
+
47
+
48
  def get_week():
49
  headers = {
50
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
 
62
  h2_tags = soup.find_all('h2')
63
  year = h2_tags[0].getText().split(' ')[0]
64
  week = h2_tags[0].getText().split(' ')[-1]
 
65
  return int(week), int(year)
66
 
67
 
 
117
  matrix = xgb.DMatrix(data.astype(float).values)
118
 
119
  # create game id
120
+ game_id = str(season) + '_0' + str(int(week)) + '_' + away_abbrev + '_' + home_abbrev
121
+ print(game_id)
 
 
 
 
 
122
 
123
  try:
124
  moneyline_result = results.loc[results['game_id']==game_id, 'winner'].item()
 
135
  moneyline = {'Winner': 'NA',
136
  'Probabilities':['N/A'],
137
  'Result': moneyline_result}
 
 
 
 
 
 
138
 
139
  try:
140
  result = results.loc[results['game_id']==game_id, 'total'].item()
Templates/index.html CHANGED
@@ -3,7 +3,7 @@
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</title>
7
  </head>
8
  <style>
9
  body {
@@ -35,6 +35,7 @@
35
  }
36
 
37
  table {
 
38
  margin-top: 20px;
39
  width: 80%;
40
  border-collapse: collapse;
@@ -95,12 +96,14 @@
95
  cursor: pointer;
96
  }
97
  .winner-wrapper {
 
98
  position: relative;
99
  width: 100%;
100
  text-align: center;
101
  display: flex;
102
  justify-content: center;
103
  align-items: center;
 
104
  }
105
  .winner-image {
106
  height: auto;
@@ -108,31 +111,15 @@
108
  transition: 0.3s ease;
109
  }
110
 
111
- .overlay {
112
- position: absolute;
113
- top: 0;
114
- left: 0;
115
- width: 100%;
116
- height: 100%;
117
- background-color: rgba(0, 0, 0, 0.8);
118
- color: white;
119
- display: flex;
120
- justify-content: center;
121
- align-items: center;
122
- opacity: 0;
123
- transition: opacity 0.3s ease;
124
- }
125
- .winner-wrapper:hover .overlay {
126
- opacity: 1;
127
- }
128
  .over-under-wrapper {
 
129
  position: relative;
130
  width: 100%;
131
  height: 50px;
132
  display: flex;
133
  align-items: center;
134
  justify-content: center;
135
- transition: opacity 0.3s ease;
136
  }
137
  .over-under-text {
138
  display: inline-block;
@@ -239,11 +226,6 @@
239
  .emoji {
240
  margin-left: 5px;
241
  color: rgb(255, 255, 255);
242
- }
243
-
244
- .emoji:hover{
245
- color:#ffffff;
246
- font-weight: bold;
247
  transition: 0.3s ease;
248
  }
249
 
@@ -275,6 +257,15 @@
275
  display: inline-block;
276
  }
277
 
 
 
 
 
 
 
 
 
 
278
  @keyframes spin {
279
  0% {
280
  transform: rotate(0deg);
@@ -328,6 +319,10 @@
328
  <span class="label">Winners:</span> {{ winners_correct }}-{{winners_incorrect}}{{winners_tie}}<span class="label"> ({{ winners_return }})</span><br>
329
  <span class="label">Over/Unders:</span> {{over_unders_correct}}-{{over_unders_incorrect}}{{over_unders_push}}<span class="label"> ({{over_unders_return}})</span><br><br>
330
  </div>
 
 
 
 
331
  <div class="table-div">
332
  <table id="gameTable">
333
  <tr>
@@ -386,10 +381,15 @@
386
 
387
 
388
  <script>
389
- async function fetchGames() {
390
- const response = await fetch('/get_games');
391
  const pulled_games = await response.json();
392
  const table = document.getElementById('gameTable');
 
 
 
 
 
393
  const columns = ['Date','Away Team', 'Home Team'];
394
  const lines_response = await fetch('/get_lines');
395
  const lines = await lines_response.json()
@@ -494,13 +494,14 @@
494
  const winnerEmojiDiv = document.createElement('div');
495
  winnerEmojiDiv.className = 'emoji';
496
 
 
497
  if (moneyline.Winner[0] === moneyline.Result) {
498
  winnerEmojiDiv.textContent = '✅';
499
  } else {
500
  winnerEmojiDiv.textContent = '❌';
501
  }
502
  if (moneyline.Result === 'N/A') {
503
- winnerEmojiDiv.textContent = `(${(moneyline.Probabilities[0] * 100).toFixed(0)}%)`;
504
  }
505
  wrapperDiv.appendChild(winnerEmojiDiv);
506
 
@@ -539,13 +540,14 @@
539
  const overEmojiDiv = document.createElement('div');
540
  overEmojiDiv.className = 'emoji';
541
 
 
542
  if (data.over_unders[index]['Over/Under'][0] === data.over_unders[index]['Result']) {
543
  overEmojiDiv.textContent = '✅';
544
  } else {
545
  overEmojiDiv.textContent = '❌';
546
  }
547
  if (data.over_unders[index]['Result'] === 'N/A') {
548
- overEmojiDiv.textContent = `(${(data.over_unders[index]['Probability'][0] * 100).toFixed(0)}%)`;
549
  }
550
  overUnderDiv.appendChild(overEmojiDiv);
551
 
@@ -554,24 +556,115 @@
554
  }, 10);
555
 
556
  overUnderCell.appendChild(overUnderDiv);
557
-
 
 
 
558
  });
559
  }
560
  });
561
 
562
  }
563
 
564
- document.getElementById('submitButton').addEventListener('click', submitData);
 
 
 
 
565
 
566
- fetchGames().then(() => {
567
- submitData();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  });
569
 
570
- document.addEventListener('keydown', function(event) {
571
- if (event.keyCode === 13) {
572
- submitData();
 
 
 
 
573
  }
574
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
 
576
 
577
  </script>
 
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 {
 
35
  }
36
 
37
  table {
38
+ transition: 0.3s ease;
39
  margin-top: 20px;
40
  width: 80%;
41
  border-collapse: collapse;
 
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;
 
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;
 
226
  .emoji {
227
  margin-left: 5px;
228
  color: rgb(255, 255, 255);
 
 
 
 
 
229
  transition: 0.3s ease;
230
  }
231
 
 
257
  display: inline-block;
258
  }
259
 
260
+ #weekSelector {
261
+ transition: 0.3s ease;
262
+ border-radius: 10px;
263
+ padding: 5px;
264
+ color: white;
265
+ background: rgb(30, 30, 30) !important;
266
+ font-family: Arial, Helvetica, sans-serif;
267
+ }
268
+
269
  @keyframes spin {
270
  0% {
271
  transform: rotate(0deg);
 
319
  <span class="label">Winners:</span> {{ winners_correct }}-{{winners_incorrect}}{{winners_tie}}<span class="label"> ({{ winners_return }})</span><br>
320
  <span class="label">Over/Unders:</span> {{over_unders_correct}}-{{over_unders_incorrect}}{{over_unders_push}}<span class="label"> ({{over_unders_return}})</span><br><br>
321
  </div>
322
+
323
+ <select id="weekSelector">
324
+ </select>
325
+
326
  <div class="table-div">
327
  <table id="gameTable">
328
  <tr>
 
381
 
382
 
383
  <script>
384
+ async function fetchGames(selectedWeek) {
385
+ const response = await fetch(`/get_games?week=${selectedWeek}`);
386
  const pulled_games = await response.json();
387
  const table = document.getElementById('gameTable');
388
+
389
+ for(let i = table.rows.length - 1; i > 0; i--) {
390
+ table.deleteRow(i);
391
+ }
392
+
393
  const columns = ['Date','Away Team', 'Home Team'];
394
  const lines_response = await fetch('/get_lines');
395
  const lines = await lines_response.json()
 
494
  const winnerEmojiDiv = document.createElement('div');
495
  winnerEmojiDiv.className = 'emoji';
496
 
497
+ wrapperDiv.dataset.proba = (moneyline.Probabilities[0] * 100).toFixed(0);
498
  if (moneyline.Winner[0] === moneyline.Result) {
499
  winnerEmojiDiv.textContent = '✅';
500
  } else {
501
  winnerEmojiDiv.textContent = '❌';
502
  }
503
  if (moneyline.Result === 'N/A') {
504
+ winnerEmojiDiv.textContent = `(${wrapperDiv.dataset.proba}%)`;
505
  }
506
  wrapperDiv.appendChild(winnerEmojiDiv);
507
 
 
540
  const overEmojiDiv = document.createElement('div');
541
  overEmojiDiv.className = 'emoji';
542
 
543
+ overUnderDiv.dataset.proba = (data.over_unders[index]['Probability'][0] * 100).toFixed(0);
544
  if (data.over_unders[index]['Over/Under'][0] === data.over_unders[index]['Result']) {
545
  overEmojiDiv.textContent = '✅';
546
  } else {
547
  overEmojiDiv.textContent = '❌';
548
  }
549
  if (data.over_unders[index]['Result'] === 'N/A') {
550
+ overEmojiDiv.textContent = `(${overUnderDiv.dataset.proba}%)`;
551
  }
552
  overUnderDiv.appendChild(overEmojiDiv);
553
 
 
556
  }, 10);
557
 
558
  overUnderCell.appendChild(overUnderDiv);
559
+
560
+ showProbabilityOnHover(wrapperDiv);
561
+ showProbabilityOnHover(overUnderDiv);
562
+
563
  });
564
  }
565
  });
566
 
567
  }
568
 
569
+ //Hover listener
570
+ function showProbabilityOnHover(div) {
571
+ let previousValue;
572
+ let divText = div.children[1];
573
+ let eventProcessed = false;
574
 
575
+ function handleEnter() {
576
+ if (eventProcessed) return; // Skip if an event has already been processed
577
+
578
+ eventProcessed = true;
579
+
580
+ if (divText.textContent !== `(${div.dataset.proba}%)`) {
581
+ divText.style.opacity = 0;
582
+
583
+ setTimeout(() => {
584
+ previousValue = divText.textContent;
585
+ divText.textContent = `(${div.dataset.proba}%)`;
586
+ divText.style.opacity = 1;
587
+ }, 300);
588
+
589
+ setTimeout(() => {
590
+ divText.style.opacity = 0;
591
+ setTimeout(() => {
592
+ divText.textContent = previousValue;
593
+ divText.style.opacity = 1;
594
+ eventProcessed = false; // Reset the flag
595
+ }, 300);
596
+ }, 1000);
597
+ }
598
+ }
599
+
600
+ // For desktop
601
+ div.addEventListener('mouseenter', handleEnter);
602
+ // For mobile
603
+ div.addEventListener('touchstart', handleEnter);
604
+ }
605
+
606
+ // Populate dropdown
607
+ let selectedWeek;
608
+ async function populateDropdown() {
609
+ const weekSelector = document.getElementById('weekSelector');
610
+ weekSelector.innerHTML = "";
611
+
612
+ const response = await fetch('/get_weeks');
613
+ const data = await response.json();
614
+
615
+ data.forEach((week, index) => {
616
+ const option = document.createElement('option');
617
+ option.value = week;
618
+ option.text = `Week ${week}`;
619
+ weekSelector.appendChild(option);
620
+
621
+ if (index === 0) {
622
+ selectedWeek = week;
623
+ }
624
+ });
625
+ }
626
+
627
+
628
+ // Get new games when new week selected
629
+ document.getElementById('weekSelector').addEventListener('change', function(event) {
630
+ selectedWeek = event.target.value;
631
+ getNew();
632
  });
633
 
634
+
635
+ // Initial load
636
+ function loadThings() {
637
+ populateDropdown()
638
+ .then(() => fetchGames(selectedWeek))
639
+ .then(() => submitData())
640
+ .catch(error => console.error(error));
641
  }
642
+
643
+ // Get new
644
+ async function getNew() {
645
+ const table = document.getElementById('gameTable');
646
+ table.style.opacity = "0.5";
647
+
648
+ try {
649
+ await fetchGames(selectedWeek);
650
+ await submitData();
651
+ table.style.opacity = "1";
652
+ } catch (error) {
653
+ console.error(error);
654
+ }
655
+ }
656
+
657
+
658
+ // Submit on click, enter, and pageload
659
+ loadThings();
660
+
661
+ document.getElementById('submitButton').addEventListener('click', submitData);
662
+
663
+ document.addEventListener('keydown', function(event) {
664
+ if (event.keyCode === 13) {
665
+ submitData();
666
+ }
667
+ });
668
 
669
 
670
  </script>
main.py CHANGED
@@ -1,5 +1,5 @@
1
  from Source.Predict import predict
2
- from flask import Flask, render_template, jsonify, request
3
  import requests
4
  import pickle as pkl
5
  import pandas as pd
@@ -7,54 +7,74 @@ import numpy as np
7
  pd.set_option('display.max_columns', None)
8
  pd.set_option('display.expand_frame_repr', False)
9
 
10
- import os
11
  import json
12
  with open('Source/Data/record.json','r') as f:
13
  record = json.load(f)
14
-
15
- # input the over/under lines here for quicker predictions!
16
- lines = [45.5,
17
- 43,
18
- 53.5,
19
- 45.5,
20
- 46,
21
- 41,
22
- 42.5,
23
- 46.5,
24
- 40.5,
25
- 43.5,
26
- 41,
27
- 48,
28
- 43,
29
- 44.5,
30
- 41.5,
31
- 47]
32
-
33
- # get week, season
34
- week, season = predict.get_week()
35
 
36
  app = Flask(__name__, template_folder="Templates", static_folder="Static", static_url_path="/Static")
 
 
 
 
37
  app.secret_key = 'green-flounder'
38
 
39
- games = predict.get_games(week)[['Date','Away Team','Home Team']]
 
 
 
 
40
 
 
41
  @app.route('/')
42
  def index():
 
 
 
43
  return render_template('index.html', **record)
44
 
 
 
 
 
 
 
45
  @app.route('/get_lines')
46
  def get_lines():
47
- return jsonify(lines)
 
 
 
48
 
 
49
  @app.route('/get_games')
50
  def get_games():
51
- return jsonify(games.to_dict(orient='records'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
 
53
  @app.route('/submit_games', methods=['POST'])
54
  def submit_games():
55
  data = request.json
56
  data = pd.DataFrame(data).replace('', np.nan).dropna()
57
- print(data)
58
  home_teams = data['HomeTeam'].values
59
  away_teams = data['AwayTeam'].values
60
  ou_lines = data['OverUnderLine'].values
@@ -63,19 +83,15 @@ def submit_games():
63
  moneylines = []
64
  over_unders = []
65
  for row_index,home,away,total in zip(row_indices,home_teams,away_teams,ou_lines):
66
- game_id, moneyline, over_under = predict.predict(home,away,season,week,total)
 
67
  moneyline['rowIndex'] = int(row_index)
68
  over_under['rowIndex'] = int(row_index)
69
  moneylines.append(moneyline)
70
  over_unders.append(over_under)
71
 
72
- print('MoneyLines')
73
- print(moneylines)
74
- print('OverUnders')
75
- print(over_unders)
76
-
77
  return jsonify({'moneylines': moneylines,
78
  'over_unders': over_unders})
79
 
80
  if __name__ == '__main__':
81
- app.run(host='0.0.0.0', port='7860')
 
1
  from Source.Predict import predict
2
+ from flask import Flask, render_template, jsonify, request, session
3
  import requests
4
  import pickle as pkl
5
  import pandas as pd
 
7
  pd.set_option('display.max_columns', None)
8
  pd.set_option('display.expand_frame_repr', False)
9
 
 
10
  import json
11
  with open('Source/Data/record.json','r') as f:
12
  record = json.load(f)
13
+ with open('Source/Data/lines.json','r') as f:
14
+ lines = json.load(f)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
  app = Flask(__name__, template_folder="Templates", static_folder="Static", static_url_path="/Static")
17
+ app.config.update(
18
+ SESSION_COOKIE_SECURE=True,
19
+ SESSION_COOKIE_SAMESITE='None',
20
+ )
21
  app.secret_key = 'green-flounder'
22
 
23
+ # get week, season
24
+ current_week, season = predict.get_week()
25
+ current_games = predict.get_games(current_week)[['Date','Away Team','Home Team']]
26
+ available_weeks = list(range(current_week+1))[2:]
27
+ available_weeks.reverse()
28
 
29
+ # load current data by default
30
  @app.route('/')
31
  def index():
32
+ print(current_week)
33
+ session['selected_week'] = current_week
34
+ session[f'games_week_{current_week}'] = current_games.to_json()
35
  return render_template('index.html', **record)
36
 
37
+ # send week list to front end
38
+ @app.route('/get_weeks')
39
+ def get_weeks():
40
+ return jsonify(available_weeks)
41
+
42
+ # send lines to front end
43
  @app.route('/get_lines')
44
  def get_lines():
45
+ try:
46
+ return jsonify(lines[str(session.get('selected_week'))])
47
+ except:
48
+ return jsonify(lines[str(current_week)])
49
 
50
+ # send games of selected week to front end
51
  @app.route('/get_games')
52
  def get_games():
53
+ requested_week = int(request.args.get('week'))
54
+ session['selected_week'] = requested_week
55
+
56
+ # If select a new week
57
+ if requested_week and requested_week != current_week:
58
+
59
+ # Check if that week's games are cached
60
+ if session.get(f'games_week_{requested_week}'):
61
+ print("Using cached games")
62
+ games = session.get(f'games_week_{requested_week}')
63
+ games = json.loads(games)
64
+ return jsonify(games)
65
+ else:
66
+ games = predict.get_games(requested_week)[['Date','Away Team','Home Team']]
67
+ session[f'games_week_{requested_week}'] = games.to_json(orient='records')
68
+ return jsonify(games.to_dict(orient='records'))
69
+ else:
70
+ games = current_games
71
+ return jsonify(games.to_dict(orient='records'))
72
 
73
+ # make predictions
74
  @app.route('/submit_games', methods=['POST'])
75
  def submit_games():
76
  data = request.json
77
  data = pd.DataFrame(data).replace('', np.nan).dropna()
 
78
  home_teams = data['HomeTeam'].values
79
  away_teams = data['AwayTeam'].values
80
  ou_lines = data['OverUnderLine'].values
 
83
  moneylines = []
84
  over_unders = []
85
  for row_index,home,away,total in zip(row_indices,home_teams,away_teams,ou_lines):
86
+ selected_week = session.get('selected_week')
87
+ game_id, moneyline, over_under = predict.predict(home,away,season,selected_week,total)
88
  moneyline['rowIndex'] = int(row_index)
89
  over_under['rowIndex'] = int(row_index)
90
  moneylines.append(moneyline)
91
  over_unders.append(over_under)
92
 
 
 
 
 
 
93
  return jsonify({'moneylines': moneylines,
94
  'over_unders': over_unders})
95
 
96
  if __name__ == '__main__':
97
+ app.run(host='0.0.0.0', port='7860', debug=True)