<jupyter_start><jupyter_text>![A.I. Sports](https://raw.githubusercontent.com/papagorgio23/Python101/master/newlogo.png)www.AISportsFirm.com  NFL Survivor Pool Optimizer ![Draft Kings](https://raw.githubusercontent.com/papagorgio23/Python101/master/DraftKings.png) We are going to tap into the Draft Kings API to access player prices and average player scores. We are then going to use this information to create optimal lineups. *   Optimial lineup = Combination of players that will score the most points  Linear Programming (The Math) The basic framework of linear/integer programming is as follows:*   There are **Decision Variables**    *  These will be the variables that we can select (i.e. which team to pick to win each week)*   There is an **Objective Function** to either Maximize or Minimize    * Our goal will be to Maximize the win probability*   There are **Constraints** we must abide by    * Only select a team once, non-negativity  Definitions:**Index Sets:**Let ***I*** be the set of Weeks in the NFL season, indexed by *i*Let ***J*** be the set of NFL teams, indexed by *j***Variables:**Let ***x*** be the teamLet ***P*** be the win probability for each matchupLet ***W*** be the week number in the season**Other Variables:**Let ***n*** be the total number of teamsLet ***m*** be the total number of weeks***$x_{ij} = Team\ Selected$$P_{ij} = Probability\ to\ win$*** implicit Form:$$maximize\ \ \ \ \ \ z = \sum_{i=1}^n\sum_{j=1}^m P_{ij} * x_{ij} $$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ subject\ to\ \ \ \ \ \sum_{i=1}^n\sum_{j=1}^m C_{ij} * x_{ij} \leq Max\ Salary$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = QB$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij}  =2, \ \ for\ \ i = RB$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =3, \ \ for\ \ i = WR$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = TE$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = FLEX$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = DST$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{i=1}^n\sum_{j=1}^m x_{ij} = 9$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ x_{ij} \geq 0,\ \forall \ i,\ j$$***  The Dream Survivor Pool RulesBasic Game-play :It's simple... make 1 pick each week, that's it!Once you pick a team, you can't pick them again, regardless if they win or lose. After you get two losses you are out unless you decide to buy-back in ($5) or join the consolation pool (If you lose twice prior to week 8 picks). Each loss after buying back in requires a buy-back to continue.**Advanced Game-play**:  There are (3) exciting twists to keep in mind:1.   Loser's Week - Week 7     *   In Week 7, you must choose a team to lose.     *   **BUT**, it has to be one of the (6) teams you selected in Weeks 1 - 6.     *   They do not need to have actually won previously to be eligble.2.   Two-pick Week - Week 14     *   In Week 14, you must select (2) teams to win.     *   Only getting both right will get you a win in the standings.      *   Any other result (outside of two ties) will get you a loss.3.   Pre-selected double-dip     *   Nominate one NON playoff team from 2018 to be your Double-Dip for 2019     *   This team may be selected twice this year with no restrictions     *   If you also pick this team in Weeks 1-6, you can pick them as your loser and use them 3 times     *   Nominations will be completed in the first pick survey. [Official Rules](https://docs.google.com/spreadsheets/d/1ePUp4tcafBpYBrkmc7BRlzZtlKx3J06dlENEzThovdM/editgid=1377458333)  Python Code  Load Libraries<jupyter_code>!pip install pulp

import urllib, json
import pandas as pd
import numpy as np
import re

from pulp import *<jupyter_output>Collecting pulp
[?25l  Downloading https://files.pythonhosted.org/packages/2d/33/3ae6d9d2ac8c7068937af6372fd8828ac605e62a8b17106fe57110930d38/PuLP-1.6.10.zip (13.6MB)
[K     |████████████████████████████████| 13.6MB 4.8MB/s 
[?25hRequirement already satisfied: pyparsing>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from pulp) (2.4.2)
Building wheels for collected packages: pulp
  Building wheel for pulp (setup.py) ... [?25l[?25hdone
  Created wheel for pulp: filename=PuLP-1.6.10-cp36-none-any.whl size=12269903 sha256=aae9fe861bb643c371031130798c4f26b3acf6b7bb916bd86103ac57b37b5f65
  Stored in directory: /root/.cache/pip/wheels/5e/76/77/e28b22219e46e3b4b033f02e8b36b2770ae545bdcf60c2b224
Successfully built pulp
Installing collected packages: pulp
Successfully installed pulp-1.6.10<jupyter_text>Get Data<jupyter_code>survivor = pd.read_csv("https://raw.githubusercontent.com/papagorgio23/Python101/master/survivor.csv")
survivor.head()<jupyter_output><empty_output><jupyter_text>Change Week 7 Probabilities to get Loss Probability<jupyter_code>survivor['Prob'] = np.where(survivor['week'] == 7, 1 - survivor['Prob'], survivor['Prob'])
survivor['week'] = survivor.apply(lambda x: "Week %s" % x['week'], axis = 1)<jupyter_output><empty_output><jupyter_text>Define The Problem  Prepare for LP formulaThe data needs to be transformed slightly differently for PuLP to work with it.$P_{ij} = Probability\ of\ Win$$x_{ij} = Team\ Selected$<jupyter_code># create 2 dictionaries: one containing the salaries of each player, the other containing the points of each player

# Win Probabilities for each matchup (P_ij)
winProbs = {} 

# loop through each position and appened player name, salary, points to correct dictionary
for week in survivor["week"].unique():
    survivor_week = survivor[survivor["week"] == week]
    winProb = list(survivor_week[["team","Prob"]].set_index("team").to_dict().values())[0]
    winProbs[week] = winProb
# Points of Player (X_ij)
teams = {} 

# loop through each position and appened player name, salary, points to correct dictionary
for team in survivor["team"].unique():
    survivor_team = survivor[survivor["team"] == team]
    team_list = list(survivor_team[["team","week"]].set_index("week").to_dict().values())[0]
    teams[team] = team_list<jupyter_output><empty_output><jupyter_text>Position Constraints$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = QB$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij}  =2, \ \ for\ \ i = RB$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =3, \ \ for\ \ i = WR$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = TE$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = FLEX$$$$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sum_{j=1}^m x_{ij} =1, \ \ for\ \ i = DST$$Flex position can be either a RB, WR, or TE. We will run 3 iterations with the flex being each on of these positions.<jupyter_code># Team Constraints
team_num_available = {
    "ARZ": 1,
    "ATL": 2,
    "BAL": 1,
    "BUF": 1,
    "CAR": 1,
    "CHI": 1,
    "CIN": 1,
    "CLE": 1,
    "DAL": 1,
    "DEN": 1,
    "DET": 1,
    "GB": 1,
    "HOU": 1,
    "IND": 1,
    "JAX": 1,
    "KC": 1,
    "LAC": 1,
    "LAR": 1,
    "MIA": 1,
    "MIN": 1,
    "NE": 1,
    "NO": 1,
    "NYG": 1,
    "NYJ": 1,
    "OAK": 1,
    "PHI": 1,
    "PIT": 1,
    "SEA": 1,
    "SF": 1,
    "TB": 1,
    "TEN": 1,
    "WAS": 1
}
# Team Constraints
week_num_available = {
    "Week 1": 1,
    "Week 2": 1,
    "Week 3": 1,
    "Week 4": 1,
    "Week 5": 1,
    "Week 6": 1,
    "Week 7": 1,
    "Week 8": 1,
    "Week 9": 1,
    "Week 10": 1,
    "Week 11": 1,
    "Week 12": 1,
    "Week 13": 1,
    "Week 14": 2,
    "Week 15": 1,
    "Week 16": 1,
    "Week 17": 1
}<jupyter_output><empty_output><jupyter_text>Create Player Variables$x_{ij} = Player$<jupyter_code># Create the variables
_vars = {i: LpVariable.dict(i, j, cat="Binary") for i, j in winProbs.items()}
# Create the variables
vars = {i: LpVariable.dict(i, j, cat="Binary") for i, j in teams.items()}
_vars.values()
_vars.items()<jupyter_output><empty_output><jupyter_text>Solve Problem<jupyter_code>team_num_available
for i, x in _vars.items():
  print([winProbs[i][j] * _vars[i][j] for j in x])
max(winProbs, key=lambda k: winProbs[k])
for i, x in _vars.items():
    print()
_vars.get("Week 2")["ARZ"]
for i in range(1,18):
  week_num = f"Week {i}"
  try:
      print(lpSum(_vars.get(week_num)["ARZ"]))
  except KeyError:
      continue
  #print(_vars.get(week_num)["ARZ"])
  #print(week_num)
for i, x in _vars.items():
  #print([1 * _vars[i][j] for j in x])
  print(_vars.get("Week 17"))
# initialize the problem statement (Maximize)
prob = LpProblem("Survivor Pool Optimizer", LpMaximize)

# initialize lists to hold constraints
winProb = []
week = []

# Setting up the reward
for i, x in _vars.items():
    #week += lpSum([teams[i][j] * _vars[i][j] for j in x])
    winProb += lpSum([winProbs[i][j] * _vars[i][j] for j in x])
    #prob += lpSum([teams[i][j] * _vars[i][j] for j in x]) <= team_num_available[i]
    prob += lpSum([_vars[i][j] for j in x]) <= week_num_available[i]
    #prob += lpSum([_vars[i][k] for k in i) <= team_num_available[i]


# Setting up the reward
for i, x in vars.items():
    prob += lpSum([vars[i][k] for k in x]) <= team_num_available[i]

#prob += lpSum(["Week_1_KC" + 'Week_2_KC'] <= 1)
# Salary Constraint
#prob += lpSum(salary) <= SALARY_CAP
    
# Objective Function
prob += lpSum(winProb)
for i, x in _vars.items():
    print(_vars[3])
    #print(lpSum([_vars[i][j] for j in x]) <= week_num_available[i])
# Setting up the reward
for i, x in vars.items():
    print(lpSum([vars[i][k] for k in x]) <= team_num_available[i])
# Setting up the reward
for i, x in _vars.items():
    print(lpSum([_vars[i][k] for k in x])) #<= team_num_available[i])
min(prices, key=lambda k: prices[k])
prob.solve()
# my beautiful function to display the results of our LP
def summary(prob):
    div = '\n-----------------------------------------\n'
    print("\n-----------------------------------------")
    print("Linear Programming Optimization Solution:")
    print("-----------------------------------------\n")
    print("Variables:\n")
    score = str(prob.objective)
    constraints = [str(const) for const in prob.constraints.values()]
    for v in prob.variables():
        score = score.replace(v.name, str(v.varValue))
        constraints = [const.replace(v.name, str(v.varValue)) for const in constraints]
        if v.varValue != 0:
            print(v.name, "=", v.varValue)
    print(div)
    print("Salary:\n")
    for constraint in constraints:
        constraint_pretty = " + ".join(re.findall("[0-9\.]*\*1.0", constraint))
        if constraint_pretty != "":
            print("{} = {}".format(constraint_pretty, eval(constraint_pretty)))
    print(div)
    print("Score:\n")
    score_pretty = " + ".join(re.findall("[0-9\.]+\*1.0", score))
    print("{} = {}".format(score_pretty, eval(score)))
    print(div)
    #print("Total Cost:  ${}".format(round(eval(constraint_pretty))))
    print("Expected Win Total: {}\n".format(round(eval(score),2)))
summary(prob)<jupyter_output>-----------------------------------------
Linear Programming Optimization Solution:
-----------------------------------------

Variables:

Week_10_LAC = 1.0
Week_11_NO = 1.0
Week_12_NE = 1.0
Week_13_KC = 1.0
Week_14_LAC = 1.0
Week_14_NO = 1.0
Week_15_BAL = 1.0
Week_16_LAR = 1.0
Week_17_NE = 1.0
Week_1_KC = 1.0
Week_2_KC = 1.0
Week_3_CHI = 1.0
Week_4_KC = 1.0
Week_5_CHI = 1.0
Week_6_LAR = 1.0
Week_7_NYJ = 1.0
Week_8_KC = 1.0
Week_9_KC = 1.0

-----------------------------------------

Salary:


-----------------------------------------

Score:

0.8424346043273551*1.0 + 0.7757088920979391*1.0 + 0.721627070178072*1.0 + 0.89689121539152*1.0 + 0.793726115014573*1.0 + 0.799931307715494*1.0 + 0.739906691787478*1.0 + 0.8140903716766469*1.0 + 0.7767250119768259*1.0 + 0.840494200989672*1.0 + 0.879831088570313*1.0 + 0.77712145748105*1.0 + 0.8599291022146751*1.0 + 0.8018707345836191*1.0 + 0.805739698163545*1.0 + 0.7575318134664171*1.0 + 0.8281947733146191*1.0 + 0.7606250196862809*1.0 = 14.47237916[...]<jupyter_text>Flex Postion = RB<jupyter_code># salary and points
salaries = {} 
points = {} 
for pos in availables["position"].unique():
    available_pos = availables[availables["position"] == pos]
    salary = list(available_pos[["displayName","salary"]].set_index("displayName").to_dict().values())[0]
    point = list(available_pos[["displayName","points"]].set_index("displayName").to_dict().values())[0]
    salaries[pos] = salary
    points[pos] = point

# Max Salary limit
SALARY_CAP = 50000


# Position Constraints
pos_num_available = {
    "QB": 1,
    "RB": 3, # FLEX POSITION = RB
    "WR": 3, 
    "TE": 1, 
    "DST": 1
}



# initialize the problem statement (Maximize)
prob = LpProblem("Fantasy Football Lineup", LpMaximize)

# Create the variables
_vars = {k: LpVariable.dict(k, v, cat="Binary") for k, v in points.items()}

# initialize lists to hold constraints
score = []
salary = []

# Setting up the reward
for k, v in _vars.items():
    salary += lpSum([salaries[k][i] * _vars[k][i] for i in v])
    score += lpSum([points[k][i] * _vars[k][i] for i in v])
    prob += lpSum([_vars[k][i] for i in v]) <= pos_num_available[k]
    

# Salary Constraint
prob += lpSum(salary) <= SALARY_CAP
    
# Objective Function
prob += lpSum(score)

prob.solve()

summary(prob)<jupyter_output><empty_output><jupyter_text>Flex Postion = WR<jupyter_code># salary and points
salaries = {} 
points = {} 
for pos in availables["position"].unique():
    available_pos = availables[availables["position"] == pos]
    salary = list(available_pos[["displayName","salary"]].set_index("displayName").to_dict().values())[0]
    point = list(available_pos[["displayName","points"]].set_index("displayName").to_dict().values())[0]
    salaries[pos] = salary
    points[pos] = point

# Max Salary limit
SALARY_CAP = 50000


# Position Constraints
pos_num_available = {
    "QB": 1,
    "RB": 2,
    "WR": 4, # FLEX POSITION = WR
    "TE": 1, 
    "DST": 1
}



# initialize the problem statement (Maximize)
prob = LpProblem("Fantasy Football Lineup", LpMaximize)

# Create the variables
_vars = {k: LpVariable.dict(k, v, cat="Binary") for k, v in points.items()}

# initialize lists to hold constraints
score = []
salary = []

# Setting up the reward
for k, v in _vars.items():
    salary += lpSum([salaries[k][i] * _vars[k][i] for i in v])
    score += lpSum([points[k][i] * _vars[k][i] for i in v])
    prob += lpSum([_vars[k][i] for i in v]) <= pos_num_available[k]
    

# Salary Constraint
prob += lpSum(salary) <= SALARY_CAP
    
# Objective Function
prob += lpSum(score)

prob.solve()

summary(prob)<jupyter_output><empty_output><jupyter_text>Flex Postion = TE<jupyter_code># salary and points
salaries = {} 
points = {} 
for pos in availables["position"].unique():
    available_pos = availables[availables["position"] == pos]
    salary = list(available_pos[["displayName","salary"]].set_index("displayName").to_dict().values())[0]
    point = list(available_pos[["displayName","points"]].set_index("displayName").to_dict().values())[0]
    salaries[pos] = salary
    points[pos] = point

# Max Salary limit
SALARY_CAP = 50000


# Position Constraints
pos_num_available = {
    "QB": 1,
    "RB": 2,
    "WR": 3,
    "TE": 2, # FLEX POSITION = TE
    "DST": 1
}



# initialize the problem statement (Maximize)
prob = LpProblem("Fantasy Football Lineup", LpMaximize)

# Create the variables
_vars = {k: LpVariable.dict(k, v, cat="Binary") for k, v in points.items()}

# initialize lists to hold constraints
score = []
salary = []

# Setting up the reward
for k, v in _vars.items():
    salary += lpSum([salaries[k][i] * _vars[k][i] for i in v])
    score += lpSum([points[k][i] * _vars[k][i] for i in v])
    prob += lpSum([_vars[k][i] for i in v]) <= pos_num_available[k]
    

# Salary Constraint
prob += lpSum(salary) <= SALARY_CAP
    
# Objective Function
prob += lpSum(score)

prob.solve()

summary(prob)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.19609528487229863, 'fraction_numerical': 0.0493614931237721, 'mean_word_length': 2.854472314245149, 'pattern_counts': {'":': 65, '<': 54, '<?xml version=': 0, '>': 40, 'https://': 5, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '465420', 'license': 'MIT', 'n_tokens_mistral': 6681, 'n_tokens_neox': 6057, 'n_words': 1541, 'path': 'Survivor_Pool.ipynb', 'repo_name': 'papagorgio23/Python101', 'size': '16288'}