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]