Пример #1
0
def print_team_for_next_gw(strat):
    """
    Display the team (inc. subs and captain) for the next gameweek
    """
    t = get_starting_squad()
    gameweeks_as_str = strat["points_per_gw"].keys()
    gameweeks_as_int = sorted([int(gw) for gw in gameweeks_as_str])
    next_gw = gameweeks_as_int[0]
    for pidout in strat["players_out"][str(next_gw)]:
        t.remove_player(pidout, gameweek=next_gw)
    for pidin in strat["players_in"][str(next_gw)]:
        t.add_player(pidin, gameweek=next_gw)
    tag = get_latest_prediction_tag()
    expected_points = t.get_expected_points(next_gw, tag)
    print(t)
Пример #2
0
def get_sell_price(team_id, player_id):

    squad = get_starting_squad(team_id)
    for p in squad.players:
        if p.player_id == player_id:
            return squad.get_sell_price_for_player(p)
Пример #3
0
def run_optimization(
    gameweeks,
    tag,
    season=CURRENT_SEASON,
    fpl_team_id=None,
    chip_gameweeks={},
    num_free_transfers=None,
    max_total_hit=None,
    allow_unused_transfers=True,
    max_transfers=2,
    num_iterations=100,
    num_thread=4,
    profile=False,
):
    """
    This is the actual main function that sets up the multiprocessing
    and calls the optimize function for every num_transfers/gameweek
    combination, to find the best strategy.
    The chip-related variables e.g. wildcard_week are -1 if that chip
    is not to be played, 0 for 'play it any week', or the gw in which
    it should be played.
    """
    discord_webhook = fetcher.DISCORD_WEBHOOK
    if fpl_team_id is None:
        fpl_team_id = fetcher.FPL_TEAM_ID

    # give the user the option to login
    fetcher.login()

    print("Running optimization with fpl_team_id {}".format(fpl_team_id))
    # How many free transfers are we starting with?
    if not num_free_transfers:
        num_free_transfers = get_free_transfers(fpl_team_id,
                                                gameweeks[0],
                                                apifetcher=fetcher)
    # create the output directory for temporary json files
    # giving the points prediction for each strategy
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    # first get a baseline prediction
    # baseline_score, baseline_dict = get_baseline_prediction(num_weeks_ahead, tag)

    # Get a dict of what chips we definitely or possibly will play
    # in each gw
    chip_gw_dict = construct_chip_dict(gameweeks, chip_gameweeks)

    # create a queue that we will add nodes to, and some processes to take
    # things off it
    squeue = CustomQueue()
    procs = []
    # create one progress bar for each thread
    progress_bars = []
    for i in range(num_thread):
        progress_bars.append(tqdm(total=100))

    # number of nodes in tree will be something like 3^num_weeks unless we allow
    # a "chip" such as wildcard or free hit, in which case it gets complicated
    num_weeks = len(gameweeks)
    num_expected_outputs = count_expected_outputs(
        num_weeks,
        next_gw=gameweeks[0],
        free_transfers=num_free_transfers,
        max_total_hit=max_total_hit,
        allow_unused_transfers=allow_unused_transfers,
        max_transfers=max_transfers,
        chip_gw_dict=chip_gw_dict,
    )
    total_progress = tqdm(total=num_expected_outputs, desc="Total progress")

    # functions to be passed to subprocess to update or reset progress bars
    def reset_progress(index, strategy_string):
        if strategy_string == "DONE":
            progress_bars[index].close()
        else:
            progress_bars[index].n = 0
            progress_bars[index].desc = "strategy: " + strategy_string
            progress_bars[index].refresh()

    def update_progress(increment=1, index=None):
        if index is None:
            # outer progress bar
            nfiles = len(os.listdir(OUTPUT_DIR))
            total_progress.n = nfiles
            total_progress.refresh()
            if nfiles == num_expected_outputs:
                total_progress.close()
                for pb in progress_bars:
                    pb.close()
        else:
            progress_bars[index].update(increment)
            progress_bars[index].refresh()

    use_api = fetcher.logged_in
    starting_squad = get_starting_squad(fpl_team_id=fpl_team_id,
                                        use_api=use_api,
                                        apifetcher=fetcher)

    if not allow_unused_transfers and (num_weeks > 1 or
                                       (num_weeks == 1
                                        and num_free_transfers == 2)):
        # if we are excluding unused transfers the tree may not include the baseline
        # strategy. In those cases quickly calculate and save it here first.
        save_baseline_score(starting_squad, gameweeks, tag, season=season)
        update_progress()

    # Add Processes to run the the target 'optimize' function.
    # This target function needs to know:
    #  num_transfers
    #  current_team (list of player_ids)
    #  transfer_dict {"gw":<gw>,"in":[],"out":[]}
    #  total_score
    #  num_free_transfers
    #  budget
    for i in range(num_thread):
        processor = Process(
            target=optimize,
            args=(
                squeue,
                i,
                num_expected_outputs,
                gameweeks,
                season,
                tag,
                chip_gw_dict,
                max_total_hit,
                allow_unused_transfers,
                max_transfers,
                num_iterations,
                update_progress,
                reset_progress,
                profile,
            ),
        )
        processor.daemon = True
        processor.start()
        procs.append(processor)
    # add starting node to the queue
    squeue.put((0, num_free_transfers, 0, starting_squad, {}, "starting"))

    for i, p in enumerate(procs):
        progress_bars[i].close()
        progress_bars[i] = None
        p.join()

    # find the best from all the strategies tried
    best_strategy = find_best_strat_from_json(tag)

    baseline_score = find_baseline_score_from_json(tag, num_weeks)
    fill_suggestion_table(baseline_score, best_strategy, season, fpl_team_id)
    for i in range(len(procs)):
        print("\n")
    print("\n====================================\n")
    print("Strategy for Team ID: {}".format(fpl_team_id))
    print("Baseline score: {}".format(baseline_score))
    print("Best score: {}".format(best_strategy["total_score"]))
    print_strat(best_strategy)
    t = print_team_for_next_gw(best_strategy, fpl_team_id)

    # If a valid discord webhook URL has been stored
    # in env variables, send a webhook message
    if discord_webhook != "MISSING_ID":
        # Use regex to check the discord webhook url is correctly formatted
        if re.match(
                r"^.*(discord|discordapp)\.com\/api\/webhooks\/([\d]+)\/([a-zA-Z0-9_-]+)$",
                discord_webhook,
        ):
            # create a formatted team lineup message for the discord webhook
            lineup_strings = [
                "__Strategy for Team ID: **{}**__".format(fpl_team_id),
                "Baseline score: *{}*".format(int(baseline_score)),
                "Best score: *{}*".format(int(best_strategy["total_score"])),
                "\n__starting 11__",
            ]
            for position in ["GK", "DEF", "MID", "FWD"]:
                lineup_strings.append("== **{}** ==\n```".format(position))
                for p in t.players:
                    if p.position == position and p.is_starting:
                        player_line = "{} ({})".format(p.name, p.team)
                        if p.is_captain:
                            player_line += "(C)"
                        elif p.is_vice_captain:
                            player_line += "(VC)"
                        lineup_strings.append(player_line)
                lineup_strings.append("```\n")
            lineup_strings.append("__subs__")
            lineup_strings.append("```")
            subs = [p for p in t.players if not p.is_starting]
            subs.sort(key=lambda p: p.sub_position)
            for p in subs:
                lineup_strings.append("{} ({})".format(p.name, p.team))
            lineup_strings.append("```\n")

            # generate a discord embed json and send to webhook
            payload = discord_payload(best_strategy, lineup_strings)
            result = requests.post(discord_webhook, json=payload)
            if 200 <= result.status_code < 300:
                print(
                    f"Discord webhook sent, status code: {result.status_code}")
            else:
                print(
                    f"Not sent with {result.status_code}, response:\n{result.json()}"
                )
        else:
            print("Warning: Discord webhook url is malformed!\n",
                  discord_webhook)
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    return
Пример #4
0
def run_optimization(
    gameweeks,
    tag,
    season=CURRENT_SEASON,
    fpl_team_id=None,
    chip_gameweeks={},
    num_free_transfers=None,
    max_total_hit=None,
    allow_unused_transfers=True,
    max_transfers=2,
    num_iterations=100,
    num_thread=4,
    profile=False,
):
    """
    This is the actual main function that sets up the multiprocessing
    and calls the optimize function for every num_transfers/gameweek
    combination, to find the best strategy.
    The chip-related variables e.g. wildcard_week are -1 if that chip
    is not to be played, 0 for 'play it any week', or the gw in which
    it should be played.
    """
    if fpl_team_id is None:
        fpl_team_id = fetcher.FPL_TEAM_ID

    print("Running optimization with fpl_team_id {}".format(fpl_team_id))
    # How many free transfers are we starting with?
    if not num_free_transfers:
        num_free_transfers = get_free_transfers(gameweeks[0], fpl_team_id)
    # create the output directory for temporary json files
    # giving the points prediction for each strategy
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    # first get a baseline prediction
    # baseline_score, baseline_dict = get_baseline_prediction(num_weeks_ahead, tag)

    # Get a dict of what chips we definitely or possibly will play
    # in each gw
    chip_gw_dict = construct_chip_dict(gameweeks, chip_gameweeks)

    # create a queue that we will add nodes to, and some processes to take
    # things off it
    squeue = CustomQueue()
    procs = []
    # create one progress bar for each thread
    progress_bars = []
    for i in range(num_thread):
        progress_bars.append(tqdm(total=100))

    # number of nodes in tree will be something like 3^num_weeks unless we allow
    # a "chip" such as wildcard or free hit, in which case it gets complicated
    num_weeks = len(gameweeks)
    num_expected_outputs = count_expected_outputs(
        num_weeks,
        next_gw=gameweeks[0],
        free_transfers=num_free_transfers,
        max_total_hit=max_total_hit,
        allow_unused_transfers=allow_unused_transfers,
        max_transfers=max_transfers,
        chip_gw_dict=chip_gw_dict,
    )
    total_progress = tqdm(total=num_expected_outputs, desc="Total progress")

    # functions to be passed to subprocess to update or reset progress bars
    def reset_progress(index, strategy_string):
        if strategy_string == "DONE":
            progress_bars[index].close()
        else:
            progress_bars[index].n = 0
            progress_bars[index].desc = "strategy: " + strategy_string
            progress_bars[index].refresh()

    def update_progress(increment=1, index=None):
        if index is None:
            # outer progress bar
            nfiles = len(os.listdir(OUTPUT_DIR))
            total_progress.n = nfiles
            total_progress.refresh()
            if nfiles == num_expected_outputs:
                total_progress.close()
                for pb in progress_bars:
                    pb.close()
        else:
            progress_bars[index].update(increment)
            progress_bars[index].refresh()

    starting_squad = get_starting_squad(fpl_team_id=fpl_team_id)

    if not allow_unused_transfers and (
        num_weeks > 1 or (num_weeks == 1 and num_free_transfers == 2)
    ):
        # if we are excluding unused transfers the tree may not include the baseline
        # strategy. In those cases quickly calculate and save it here first.
        save_baseline_score(starting_squad, gameweeks, tag, season=season)
        update_progress()

    # Add Processes to run the the target 'optimize' function.
    # This target function needs to know:
    #  num_transfers
    #  current_team (list of player_ids)
    #  transfer_dict {"gw":<gw>,"in":[],"out":[]}
    #  total_score
    #  num_free_transfers
    #  budget
    for i in range(num_thread):
        processor = Process(
            target=optimize,
            args=(
                squeue,
                i,
                num_expected_outputs,
                gameweeks,
                season,
                tag,
                chip_gw_dict,
                max_total_hit,
                allow_unused_transfers,
                max_transfers,
                num_iterations,
                update_progress,
                reset_progress,
                profile,
            ),
        )
        processor.daemon = True
        processor.start()
        procs.append(processor)
    # add starting node to the queue
    squeue.put((0, num_free_transfers, 0, starting_squad, {}, "starting"))

    for i, p in enumerate(procs):
        progress_bars[i].close()
        progress_bars[i] = None
        p.join()

    # find the best from all the strategies tried
    best_strategy = find_best_strat_from_json(tag)

    baseline_score = find_baseline_score_from_json(tag, num_weeks)
    fill_suggestion_table(baseline_score, best_strategy, season, fpl_team_id)
    for i in range(len(procs)):
        print("\n")
    print("\n====================================\n")
    print("Strategy for Team ID: {}".format(fpl_team_id))
    print("Baseline score: {}".format(baseline_score))
    print("Best score: {}".format(best_strategy["total_score"]))
    print_strat(best_strategy)
    print_team_for_next_gw(best_strategy, fpl_team_id)
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    return
Пример #5
0
def run_optimization(
    gameweeks,
    tag,
    season=CURRENT_SEASON,
    wildcard=False,
    free_hit=False,
    triple_captain=False,
    bench_boost=False,
    num_free_transfers=None,
    num_iterations=100,
    num_thread=4,
    profile=False,
):
    """
    This is the actual main function that sets up the multiprocessing
    and calls the optimize function for every num_transfers/gameweek
    combination, to find the best strategy.
    """
    ## How many free transfers are we starting with?
    if not num_free_transfers:
        num_free_transfers = get_free_transfers(gameweeks[0])
    ## create the output directory for temporary json files
    ## giving the points prediction for each strategy
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    ## first get a baseline prediction
    # baseline_score, baseline_dict = get_baseline_prediction(num_weeks_ahead, tag)

    ## create a queue that we will add nodes to, and some processes to take
    ## things off it
    squeue = CustomQueue()
    procs = []
    ## create one progress bar for each thread
    progress_bars = []
    for i in range(num_thread):
        progress_bars.append(tqdm(total=100))

    ## number of nodes in tree will be something like 3^num_weeks unless we allow
    ## a "card" such as wildcard or free hit, in which case it gets complicated
    num_weeks = len(gameweeks)
    expected_num = count_expected_outputs(0, num_weeks, wildcard, free_hit,
                                          triple_captain, bench_boost)
    total_progress = tqdm(total=expected_num, desc="Total progress")

    ## functions to be passed to subprocess to update or reset progress bars
    def reset_progress(index, strategy_string):
        if strategy_string == "DONE":
            progress_bars[index].close()
        else:
            progress_bars[index].n = 0
            progress_bars[index].desc = "strategy: " + strategy_string
            progress_bars[index].refresh()

    def update_progress(increment=1, index=None):
        if index == None:
            ## outer progress bar
            nfiles = len(os.listdir(OUTPUT_DIR))
            total_progress.n = nfiles
            total_progress.refresh()
            if nfiles == expected_num:
                total_progress.close()
                for pb in progress_bars:
                    pb.close()
        else:
            progress_bars[index].update(increment)
            progress_bars[index].refresh()

    ## Add Processes to run the the target 'optimize' function.
    ## This target function needs to know:
    ##  num_transfers
    ##  current_team (list of player_ids)
    ##  transfer_dict {"gw":<gw>,"in":[],"out":[]}
    ##  total_score
    ##  num_free_transfers
    ##  budget
    cards = []
    if wildcard:
        cards.append("wildcard")
    if free_hit:
        cards.append("free_hit")
    if triple_captain:
        cards.append("triple_captain")
    if bench_boost:
        cards.append("bench_boost")
    for i in range(num_thread):
        processor = Process(
            target=optimize,
            args=(
                squeue,
                i,
                gameweeks,
                season,
                tag,
                cards,
                num_iterations,
                update_progress,
                reset_progress,
                profile,
            ),
        )
        processor.daemon = True
        processor.start()
        procs.append(processor)
    ## add starting node to the queue
    starting_squad = get_starting_squad()
    squeue.put((0, num_free_transfers, starting_squad, {}, "starting"))

    for i, p in enumerate(procs):
        progress_bars[i].close()
        progress_bars[i] = None
        p.join()

    ### find the best from all the strategies tried
    best_strategy = find_best_strat_from_json(tag)

    baseline_score = find_baseline_score_from_json(tag, num_weeks)
    fill_suggestion_table(baseline_score, best_strategy, season)
    for i in range(len(procs)):
        print("\n")
    print("\n====================================\n")
    print("Baseline score: {}".format(baseline_score))
    print("Best score: {}".format(best_strategy["total_score"]))
    print_strat(best_strategy)
    print_team_for_next_gw(best_strategy)
    shutil.rmtree(OUTPUT_DIR, ignore_errors=True)
    return