File size: 3,189 Bytes
d04558f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
import streamlit as st
import numpy as np
import pandas as pd
import time
from fuzzywuzzy import process
def optimize_lineup(row):
current_lineup = []
total_salary = 0
salary_cap = 50000
used_players = set()
# Convert row to dictionary with roster positions
roster = {}
for col, player in zip(row.index, row):
if col not in ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Lineup Edge']:
roster[col] = {
'name': player,
'position': map_dict['pos_map'].get(player, '').split('/'),
'team': map_dict['team_map'].get(player, ''),
'salary': map_dict['salary_map'].get(player, 0),
'median': map_dict['proj_map'].get(player, 0),
'ownership': map_dict['own_map'].get(player, 0)
}
total_salary += roster[col]['salary']
used_players.add(player)
# Optimize each roster position in random order
roster_positions = list(roster.items())
random.shuffle(roster_positions)
for roster_pos, current in roster_positions:
# Skip optimization for players from removed teams
if current['team'] in remove_teams_var:
continue
valid_positions = position_rules[roster_pos]
better_options = []
# Find valid replacements for this roster position
for pos in valid_positions:
if pos in position_groups:
pos_options = [
p for p in position_groups[pos]
if p['median'] > current['median']
and (total_salary - current['salary'] + p['salary']) <= salary_cap
and p['player_names'] not in used_players
and any(valid_pos in p['positions'] for valid_pos in valid_positions)
and map_dict['team_map'].get(p['player_names']) not in remove_teams_var # Check team restriction
]
better_options.extend(pos_options)
if better_options:
# Remove duplicates
better_options = {opt['player_names']: opt for opt in better_options}.values()
# Sort by median projection and take the best one
best_replacement = max(better_options, key=lambda x: x['median'])
# Update the lineup and tracking variables
used_players.remove(current['name'])
used_players.add(best_replacement['player_names'])
total_salary = total_salary - current['salary'] + best_replacement['salary']
roster[roster_pos] = {
'name': best_replacement['player_names'],
'position': map_dict['pos_map'][best_replacement['player_names']].split('/'),
'team': map_dict['team_map'][best_replacement['player_names']],
'salary': best_replacement['salary'],
'median': best_replacement['median'],
'ownership': best_replacement['ownership']
}
# Return optimized lineup maintaining original column order
return [roster[pos]['name'] for pos in row.index if pos in roster] |