Code works fine except...

Ross ross.jett at gmail.com
Mon May 4 12:01:05 EDT 2009


On May 3, 8:29 pm, John Machin <sjmac... at lexicon.net> wrote:
> On May 4, 12:36 pm, Ross <ross.j... at gmail.com> wrote:
>
>
>
> > For the past couple weeks, I've been working on an algorithm to
> > schedule tennis leagues given court constraints and league
> > considerations (i.e. whether it's a singles or a doubles league). Here
> > were my requirements when I was designing this algorithm:
>
> > -Each player plays against a unique opponent each week.
> > -Similarly, in a doubles league, each player plays with a unique
> > partner each week.
> > -Each player gets a fair number of bye weeks (i.e. the player with the
> > most bye weeks will have no more than one bye week than the player
> > with the least number of bye weeks)
>
> > I'm very close to arriving at my desired solution, but I have one
> > glaring flaw. When I have an even number of players sign up for my
> > league and there are court constraints, my current algorithm gives the
> > first player in my league a bye week every single week. I'll post my
> > code below and see how you guys think I should add to/ amend my code.
>
> > def round_robin(players, rounds):
> >     if len(players)%2:
> >         players.insert(0, None)
> >     mid = len(players)//2
> >     for i in range(rounds):
> >         yield zip(players[:mid], players[mid:])
> >         players = players[0:1] + players[mid:mid+1] + players[1:mid-1] +
> > players[mid+1:] + players[mid-1:mid]
>
> > def test_round_robin(players, rounds, courts, doubles = False):
> >     players = range(players)
>
> DON'T change the type/contents/meaning of a variable name like that.
> E.g. use "nthings" for a number of things and "things" for a
> collection of things.
>
> >     for week in round_robin(players,rounds,courts):
>
> The round_robin() function has only TWO arguments. This code won't
> even run.
>
> When you document neither your data structures nor what your functions
> are intended to do, the last hope for somebody trying to make sense of
> your code is to give meaningful names to your variables. "week" and
> "doubles_week" are NOT meaningful.
>
> >             if doubles == True:
>
> Bletch. s/ == True//
>
> >                     doubles_week = len(week)/2.0
>
> I doubt very much that using floating point is a good idea here.
>
> >                     byes = doubles_week - courts
> >                     if byes == 0:
> >                             bye_list = []
> >                     else:
> >                             bye_list = week[::int(round(1.072*(courts/byes)+1.08))]
>
> The derivation of the constants 1.072 and 1.08 is .... what?
>
> >                     playing = [u for u in week if u not in bye_list]
> >                     midd = len(playing)//2
> >                     doub_sched = zip(playing[:midd], playing[midd:])
> >                     print doub_sched, bye_list
> >             else:
> >                     byes = len(week)- courts
> >                     if byes == 0:
> >                             bye_list = []
> >                     else:
> >                             bye_list = week[::int(round(1.072*(courts/byes)+1.08))]
> >                     playing = [u for u in week if u not in bye_list]
> >                     print playing, bye_list

For everybody's enlightenment, I have gone through and commented my
code so you can better understand what I'm doing. Here it is:

def round_robin(players, rounds):
    # if number of players odd, insert None at first position
    if len(players)%2:
	players.insert(0, None)
    mid = len(players)//2
    for i in range(rounds):
	yield zip(players[:mid], players[mid:])
	players = players[0:1] + players[mid:mid+1] + players[1:mid-1] +
players[mid+1:] + players[mid-1:mid]
""" rotates players like this: 1 2  ->  3 -> 4

                                         /            |

                                       5 <- 6 <-7 <- 8 """

def test_round_robin(players, rounds, courts, doubles = False):
    players = range(players)
    for week in round_robin(players,rounds):
	    if doubles == True: #for doubles pairings
		    doubles_week = len(week)/2.0
		    byes = doubles_week - courts #number of tuples to be put into
bye_list
		    if byes == 0:
			    bye_list = []
		    else: """ following formula equally spaces out tuples selected
for bye_list and selects appropriate number according to length of the
league"""
			    bye_list = week[::int(round(1.072*(courts/byes)+1.08))]
		    playing = [u for u in week if u not in bye_list]
		    midd = len(playing)//2
		    doub_sched = zip(playing[:midd], playing[midd:])#matches the
remaining tuples into doubles matches
		    print doub_sched, bye_list
	    else:
		    byes = len(week)- courts
		    if byes == 0:
			    bye_list = []
		    else:
			    bye_list = week[::int(round(1.072*(courts/byes)+1.08))]
		    playing = [u for u in week if u not in bye_list]
		    print playing, bye_list



More information about the Python-list mailing list