Create all combination of IPL cricket teams with validation criteria

Viewed 4925

So, I place bets on Dream11 app. In the app, you have to select your team of 11 out of playing 22 players. It has some constraints on a valid team.

Constraints(eg. CSK vs. MI):
Number of wicket keepers can be from 1 to 4
Number of batsmen can be from 3 to 6
Number of allrounders can be from 1 to 4
Number of bowlers can be from 3 to 6
Number of players selected from CSK should be less than equal to 7
Number of players selected from MI should be less than equal to 7
Sum Credits of all the selected players should be less than equal to 100

Now the thing is that sometimes creating these team becomes a really difficult task when they release the lineups and a lot of players you selected are not playing or when one of the playing team is way stronger than other. So, I thought of making a program in which I can input the playing 22 and I can get all the valid teams of 11 players that I can make.

Here is the input file format:
(The first line is just for reference, it's not there in the original file. Every column is tab-separated because it is easy to copy-paste from Excel that way.)


#Name   #Credit   #Team1   #Team2   #WK   #BAT   #ALL   #BOWL   #Sel
Glenn Maxwell   8.5 1   0   0   0   1   0   0
Chris Woakes    9   0   1   0   0   1   0   0
Mitchell Marsh  8   1   0   0   0   1   0   0
Marcus Stoinis  8.5 1   0   0   0   1   0   0
Jonny Bairstow  9.5 0   1   1   0   0   0   0
Jos Buttler 9.5 0   1   1   0   0   0   0
Alex Carey  8.5 1   0   1   0   0   0   0
Eoin Morgan 9   0   1   0   1   0   0   0
Sam Billings    8   0   1   0   1   0   0   0
Joe Root    10  0   1   0   1   0   0   0
David Warner    10  1   0   0   1   0   0   0
Aaron Finch 9.5 1   0   0   1   0   0   0
Marnus Labuschagne  8.5 1   0   0   1   0   0   0
Jason Roy   9   0   1   0   1   0   0   0
Jofra Archer    9   0   1   0   0   0   1   0
Tom Curran  8.5 0   1   0   0   0   1   0
Adil Rashid 9   0   1   0   0   0   1   0
Mark Wood   8.5 0   1   0   0   0   1   0
Josh Hazlewood  8.5 1   0   0   0   0   1   0
Mitchell Starc  9   1   0   0   0   0   1   0
Pat Cummins 9   1   0   0   0   0   1   0
Adam Zampa  8.5 1   0   0   0   0   1   0

The Credit column has credit for the respective player. In all other columns, 0 represents that the respective player is not that thing and 1 represents that the respective player is that thing(eg. 1 in Team1 column represents that player is in Actual Playing Team 1 and 1 in the WK column represents that player is wicket-keeper.)

Here is what I programmed to do this task.

import itertools
ValidTeam = []
with open("Players.txt", "r") as dfile:
    players = [t for t in dfile.read().split("\n")]
combos = list(itertools.combinations(players, 11))
for combo in combos:
    crd, t1, t2, wk, bat, alr, bowl = 0, 0, 0, 0, 0, 0, 0
    for tplayer in combo:
        player = tplayer.split("\t")
        crd += float(player[1])
        t1 += int(player[2])
        t2 += int(player[3])
        wk += int(player[4])
        bat += int(player[5])
        alr += int(player[6])
        bowl += int(player[7])
    if crd <= 100 and t1 <= 7 and t2 <= 7 and (wk in range(1,5)) and (bat in range(3,7)) and (alr in range(1,5)) and (bowl in range(3,7)):
        ValidTeam.append(combo)
        print(player)
    print("")
print(ValidTeam)

Now the problem is for some reason that I don't understand it is showing this error message

Traceback (most recent call last):
  File "C:\Users\RACHIT\Desktop\TM.py", line 12, in <module>
    crd += float(player[1])
IndexError: list index out of range

Please, help me out with this problem. Also, since there will be 22C11 possible teams and for the future, chosen captains and vice-captains have special privileges so that makes it 2! * 22C11, plus the validation part of that many teams, plus I'm thinking of processing those valid teams too in future to choose the best out of them, so it can take a lot of time to process. So ideas to make it faster, efficient and better will be much appreciated and welcomed.

PS: I'm using itertools for the first time so don't have much idea about it but it so really convenient.

2 Answers

Scope for improvements:

  1. players = [t.split('\t') for t in dfile.read().split("\n")]

    String operations are expensive. Instead of doing it later after generating combinations, do it before. This way you will only do it once for all players.

  2. You can process combos in parallel. Convert your inner loop to a function that processes a list. Use pool.map.

Example implementation:

import multiprocessing as mp

def fun(combo):
    # Implement your logic here for one team, similar to your logic inside current for loop
    # return True if valid else if invalid return False 

if __name__ == '__main__':
    .
    .  # Implement reading players from file and generating list of combinations
    .

    num_workers = mp.cpu_count()
    with mp.Pool(num_workers) as pool:
        valid_teams = [c for c, keep in zip(combos, pool.map(fun, combos)) if keep]

    # do something with valid_teams

Reference: https://docs.python.org/3/library/multiprocessing.html

list index out of range implies that you are trying to access an array index which does not exist,

player[1] assumes that the player array formed in tplayer.split("\t") has at least 2 elements. the split has not resulted in such an array, fixing that should help

Related