import pulp import numpy as np import pandas as pd import random import sys import openpyxl import re import time import streamlit as st import matplotlib from matplotlib.colors import LinearSegmentedColormap import json import requests import gspread import plotly.figure_factory as ff scope = ['https://www.googleapis.com/auth/spreadsheets', "https://www.googleapis.com/auth/drive"] credentials = { "type": "service_account", "project_id": "sheets-api-connect-378620", "private_key_id": "1005124050c80d085e2c5b344345715978dd9cc9", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtKa01beXwc88R\nnPZVQTNPVQuBnbwoOfc66gW3547ja/UEyIGAF112dt/VqHprRafkKGmlg55jqJNt\na4zceLKV+wTm7vBu7lDISTJfGzCf2TrxQYNqwMKE2LOjI69dBM8u4Dcb4k0wcp9v\ntW1ZzLVVuwTvmrg7JBHjiSaB+x5wxm/r3FOiJDXdlAgFlytzqgcyeZMJVKKBQHyJ\njEGg/1720A0numuOCt71w/2G0bDmijuj1e6tH32MwRWcvRNZ19K9ssyDz2S9p68s\nYDhIxX69OWxwScTIHLY6J2t8txf/XMivL/636fPlDADvBEVTdlT606n8CcKUVQeq\npUVdG+lfAgMBAAECggEAP38SUA7B69eTfRpo658ycOs3Amr0JW4H/bb1rNeAul0K\nZhwd/HnU4E07y81xQmey5kN5ZeNrD5EvqkZvSyMJHV0EEahZStwhjCfnDB/cxyix\nZ+kFhv4y9eK+kFpUAhBy5nX6T0O+2T6WvzAwbmbVsZ+X8kJyPuF9m8ldcPlD0sce\ntj8NwVq1ys52eosqs7zi2vjt+eMcaY393l4ls+vNq8Yf27cfyFw45W45CH/97/Nu\n5AmuzlCOAfFF+z4OC5g4rei4E/Qgpxa7/uom+BVfv9G0DIGW/tU6Sne0+37uoGKt\nW6DzhgtebUtoYkG7ZJ05BTXGp2lwgVcNRoPwnKJDxQKBgQDT5wYPUBDW+FHbvZSp\nd1m1UQuXyerqOTA9smFaM8sr/UraeH85DJPEIEk8qsntMBVMhvD3Pw8uIUeFNMYj\naLmZFObsL+WctepXrVo5NB6RtLB/jZYxiKMatMLUJIYtcKIp+2z/YtKiWcLnwotB\nWdCjVnPTxpkurmF2fWP/eewZ+wKBgQDRMtJg7etjvKyjYNQ5fARnCc+XsI3gkBe1\nX9oeXfhyfZFeBXWnZzN1ITgFHplDznmBdxAyYGiQdbbkdKQSghviUQ0igBvoDMYy\n1rWcy+a17Mj98uyNEfmb3X2cC6WpvOZaGHwg9+GY67BThwI3FqHIbyk6Ko09WlTX\nQpRQjMzU7QKBgAfi1iflu+q0LR+3a3vvFCiaToskmZiD7latd9AKk2ocsBd3Woy9\n+hXXecJHPOKV4oUJlJgvAZqe5HGBqEoTEK0wyPNLSQlO/9ypd+0fEnArwFHO7CMF\nycQprAKHJXM1eOOFFuZeQCaInqdPZy1UcV5Szla4UmUZWkk1m24blHzXAoGBAMcA\nyH4qdbxX9AYrC1dvsSRvgcnzytMvX05LU0uF6tzGtG0zVlub4ahvpEHCfNuy44UT\nxRWW/oFFaWjjyFxO5sWggpUqNuHEnRopg3QXx22SRRTGbN45li/+QAocTkgsiRh1\nqEcYZsO4mPCsQqAy6E2p6RcK+Xa+omxvSnVhq0x1AoGAKr8GdkCl4CF6rieLMAQ7\nLNBuuoYGaHoh8l5E2uOQpzwxVy/nMBcAv+2+KqHEzHryUv1owOi6pMLv7A9mTFoS\n18B0QRLuz5fSOsVnmldfC9fpUc6H8cH1SINZpzajqQA74bPwELJjnzrCnH79TnHG\nJuElxA33rFEjbgbzdyrE768=\n-----END PRIVATE KEY-----\n", "client_email": "gspread-connection@sheets-api-connect-378620.iam.gserviceaccount.com", "client_id": "106625872877651920064", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40sheets-api-connect-378620.iam.gserviceaccount.com" } gc = gspread.service_account_from_dict(credentials) st.set_page_config(layout="wide") dk_player_url = 'PGA_Basic_ROO' CSV_URL = 'https://sheetdb.io/api/v1/ckjq8yp37qxly?sheet=DK_CSV' @st.cache_data def load_dk_player_model(URL): sh = gc.open(URL) worksheet = sh.get_worksheet(0) raw_display = pd.DataFrame(worksheet.get_all_records()) raw_display["Salary"] = raw_display["Salary"].replace("$", "", regex=True).astype(float) raw_display['Top_finish'] = raw_display['Top_finish'].str.replace('%', '').astype(float)/100 raw_display['Top_5_finish'] = raw_display['Top_5_finish'].str.replace('%', '').astype(float)/100 raw_display['Top_10_finish'] = raw_display['Top_10_finish'].str.replace('%', '').astype(float)/100 raw_display['100+%'] = raw_display['100+%'].str.replace('%', '').astype(float)/100 raw_display['10x%'] = raw_display['10x%'].str.replace('%', '').astype(float)/100 raw_display['11x%'] = raw_display['11x%'].str.replace('%', '').astype(float)/100 raw_display['12x%'] = raw_display['12x%'].str.replace('%', '').astype(float)/100 raw_display['LevX'] = raw_display['LevX'].str.replace('%', '').astype(float)/100 return raw_display @st.cache_data def grab_csv_data(URL): draftkings_data = pd.read_json(URL) draftkings_data.rename(columns={"Name": "Player"}, inplace = True) return draftkings_data tab1, tab2 = st.tabs(["Player Overall Projections", "Optimizer"]) def convert_df_to_csv(df): return df.to_csv().encode('utf-8') lineup_display = [] check_list = [] rand_player = 0 boost_player = 0 salaryCut = 0 with tab1: if st.button("Reset Data", key='reset1'): # Clear values from *all* all in-memory and on-disk data caches: # i.e. clear values from both square and cube st.cache_data.clear() hold_display = load_dk_player_model(dk_player_url) csv_data = grab_csv_data(CSV_URL) csv_merge = pd.merge(csv_data, hold_display, how='left', left_on=['Player'], right_on = ['Player']) id_dict = dict(zip(csv_merge['Player'], csv_merge['Name + ID'])) hold_container = st.empty() display = hold_display.set_index('Player') st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True) st.download_button( label="Export Projections", data=convert_df_to_csv(display), file_name='PGA_DFS_export.csv', mime='text/csv', ) with tab2: col1, col2 = st.columns([1, 4]) with col1: max_sal = st.number_input('Max Salary', min_value = 35000, max_value = 50000, value = 50000, step = 100) min_sal = st.number_input('Min Salary', min_value = 35000, max_value = 49900, value = 49000, step = 100) proj_cut = st.number_input('Lowest median allowed', min_value = 0, max_value = 100, value = 50, step = 1) slack_var = st.number_input('Median randomness', min_value = 0, max_value = 5, value = 0, step = 1) totalRuns_raw = st.number_input('How many Lineups', min_value = 1, max_value = 1000, value = 5, step = 1) totalRuns = totalRuns_raw cut_group_1 = [] cut_group_2 = [] force_group_1 = [] force_group_2 = [] avoid_players = [] lock_player = [] lineups = [] player_pool_raw = [] player_pool = [] player_count = [] player_trim_pool = [] portfolio = pd.DataFrame() x = 1 if st.button('Optimize'): max_proj = 1000 max_own = 1000 total_proj = 0 total_own = 0 with col2: with st.spinner('Wait for it...'): with hold_container.container(): while x <= totalRuns: raw_proj_file = hold_display raw_flex_file = raw_proj_file.dropna(how='all') raw_flex_file = raw_flex_file.loc[raw_flex_file['Median'] > 0] raw_flex_file = raw_flex_file.loc[raw_flex_file['Median'] > proj_cut] flex_file = raw_flex_file flex_file = flex_file[['Player', 'Salary', 'Median', 'Own', 'LevX']] flex_file.rename(columns={"Own": "Proj DK Own%"}, inplace = True) flex_file['name_var'] = flex_file['Player'] flex_file['lock'] = flex_file['Player'].isin(lock_player)*1 flex_file['force_group_1'] = flex_file['Player'].isin(force_group_1)*1 flex_file['force_group_2'] = flex_file['Player'].isin(force_group_2)*1 flex_file['cut_group_1'] = flex_file['Player'].isin(cut_group_1)*1 flex_file['cut_group_2'] = flex_file['Player'].isin(cut_group_2)*1 chalk_file = flex_file.sort_values(by='Proj DK Own%', ascending=False) chalk_group_df = chalk_file.sample(n=10) chalk_group = chalk_group_df['Player'].tolist() flex_file['chalk_group'] = flex_file['Player'].isin(chalk_group)*1 flex_file['Pos'] = 'G' flex_file = flex_file[['Player', 'name_var', 'Pos', 'Salary', 'Median', 'Proj DK Own%', 'lock', 'force_group_1', 'force_group_2', 'cut_group_1', 'cut_group_2', 'chalk_group', 'LevX']] if x > 1: if slack_var > 0: flex_file['randNumCol'] = np.random.randint(-int(slack_var),int(slack_var), flex_file.shape[0]) elif slack_var ==0: flex_file['randNumCol'] = 0 elif x == 1: flex_file['randNumCol'] = 0 flex_file['Median'] = flex_file['Median'] + flex_file['randNumCol'] flex_file_check = flex_file check_list.append(flex_file['Median'][4]) player_ids = flex_file.index overall_players = flex_file[['Player']] overall_players['player_var_add'] = flex_file.index overall_players['player_var'] = 'player_vars_' + overall_players['player_var_add'].astype(str) player_vars = pulp.LpVariable.dicts("player_vars", flex_file.index, 0, 1, pulp.LpInteger) total_score = pulp.LpProblem("Fantasy_Points_Problem", pulp.LpMaximize) player_match = dict(zip(overall_players['player_var'], overall_players['Player'])) player_index_match = dict(zip(overall_players['player_var'], overall_players['player_var_add'])) player_own = dict(zip(flex_file['Player'], flex_file['Proj DK Own%'])) player_sal = dict(zip(flex_file['Player'], flex_file['Salary'])) player_lev = dict(zip(flex_file['Player'], flex_file['LevX'])) player_proj = dict(zip(flex_file['Player'], flex_file['Median'])) obj_points = {idx: (flex_file['Median'][idx]) for idx in flex_file.index} total_score += sum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) obj_points_max = {idx: (flex_file['Median'][idx]) for idx in flex_file.index} obj_own_max = {idx: (flex_file['Proj DK Own%'][idx]) for idx in flex_file.index} obj_salary = {idx: (flex_file['Salary'][idx]) for idx in flex_file.index} total_score += pulp.lpSum([player_vars[idx]*obj_salary[idx] for idx in flex_file.index]) <= max_sal total_score += pulp.lpSum([player_vars[idx]*obj_salary[idx] for idx in flex_file.index]) >= min_sal for flex in flex_file['Pos'].unique(): sub_idx = flex_file[flex_file['Pos'] != "Var"].index total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == 6 player_count = [] player_trim = [] lineup_list = [] total_score += pulp.lpSum([player_vars[idx]*obj_points_max[idx] for idx in flex_file.index]) <= max_proj - .01 total_score.solve() for v in total_score.variables(): if v.varValue > 0: lineup_list.append(v.name) df = pd.DataFrame(lineup_list) df['Names'] = df[0].map(player_match) df['Cost'] = df['Names'].map(player_sal) df['Proj'] = df['Names'].map(player_proj) df['Own'] = df['Names'].map(player_own) total_cost = sum(df['Cost']) total_own = sum(df['Own']) total_proj = sum(df['Proj']) lineup_raw = pd.DataFrame(lineup_list) lineup_raw['Names'] = lineup_raw[0].map(player_match) lineup_raw['value'] = lineup_raw[0].map(player_index_match) lineup_final = lineup_raw.sort_values(by=['value']) del lineup_final[lineup_final.columns[0]] del lineup_final[lineup_final.columns[1]] lineup_final = lineup_final.reset_index(drop=True) lineup_test = lineup_final lineup_final = lineup_final.T lineup_final['Cost'] = total_cost lineup_final['Proj'] = total_proj lineup_final['Own'] = total_own if total_cost < 50001: lineups.append(lineup_final) lineup_test['Salary'] = lineup_test['Names'].map(player_sal) lineup_test['Proj'] = lineup_test['Names'].map(player_proj) lineup_test['Own'] = lineup_test['Names'].map(player_own) lineup_test['LevX'] = lineup_test['Names'].map(player_lev) lineup_test.loc['Column_Total'] = lineup_test.sum(numeric_only=True, axis=0) lineup_display.append(lineup_test) with col2: with st.container(): st.table(lineup_test) max_proj = total_proj max_own = total_own check_list.append(total_proj) portfolio = portfolio.append(lineup_final, ignore_index = True) x += 1 portfolio.rename(columns={0: "Player_1", 1: "Player_2", 2: "Player_3", 3: "Player_4", 4: "Player_5", 5: "Player_6"}, inplace = True) portfolio = portfolio.dropna() final_outcomes = portfolio final_outcomes['p1 id'] = final_outcomes['Player_1'].map(id_dict) final_outcomes['p2 id'] = final_outcomes['Player_2'].map(id_dict) final_outcomes['p3 id'] = final_outcomes['Player_3'].map(id_dict) final_outcomes['p4 id'] = final_outcomes['Player_4'].map(id_dict) final_outcomes['p5 id'] = final_outcomes['Player_5'].map(id_dict) final_outcomes['p6 id'] = final_outcomes['Player_6'].map(id_dict) final_outcomes = final_outcomes[['p1 id', 'p2 id', 'p3 id', 'p4 id', 'p5 id', 'p6 id']] with col1: st.download_button( label="Export Lineups", data=convert_df_to_csv(final_outcomes), file_name='PGA_DFS_export.csv', mime='text/csv', ) with hold_container: hold_container = st.empty()