Re: Code works fine except...

2009-05-09 Thread Arnaud Delobelle
John Yeung gallium.arsen...@gmail.com writes:

 On May 5, 11:37 pm, Ross ross.j...@gmail.com wrote:

 On May 5, 10:33 am, MRAB goo...@mrabarnett.plus.com wrote:

  Here's my approach (incomplete):

 FYI... I was testing your code further and discovered a strange
 outcome... when there are 16 people for 7 courts, every 7th
 round your code produces 4 byes instead of the correct 2 byes.

 Well, MRAB did say his was incomplete, and it's significantly shorter
 and cleaner than mine.

 Mine has even weirder-looking behavior at 16 players on 7 courts, but
 I think it's because mine tries harder to keep things balanced.  After
 a few rounds, the inequalities start to build up, and my routine picks
 some people more often to catch up, but it doesn't prevent the same
 person from being scheduled for multiple matches the same week.  There
 may also be other, more subtle ways mine is broken.

 It also may be that the problem is inherently unsolvable for some
 values.  (I'm still waiting for someone with sufficient math ability
 to swoop in and either provide a way that works for all values, or
 confirm that there are just some unavoidable pathological cases.)

 John

I was thinking about this problem today.  What is needed is to generate
all matches between n players in an order such that any sequence of
(n//2-1) matches does not repeat any player.  If there are an even
number of players, this guarantees an even distribution of byes as well
(i.e. a difference of at most 1 between the highest and lowest number of
byes).  Unfortunately, if there are an odd number of players, I don't
think this is achievable because there are two sources of byes
unbalance:

* a player needs to be left out of each 'complete round' (where each
  player plays each other'

* some players are left out of each weekly round because there are not
  enough tennis courts for a complete round to be played in one week.

What I believe is achievable in the case of an odd number of players is
a difference of at most two between the highest and the lowest number of
byes for any player at any point in the tournament.

I don't have a proof of this because I haven't had the time to think
about it for long enough, but I have a toy implementation which I have
tested in a very limited manner.  I think it will generate tournaments
with the property that bye imbalance never exceeds 2. I also think it is
not possible to achieve better in general (it's a conjecture!).


from itertools import count

def matches(players):
Generates all matches between players
n = len(players)
if n % 2:
for i in xrange(n):
for j in xrange(1, 1 + n/2):
yield players[(i+j)%n], players[(i-j)%n]
else:
m = n - 1
for i in xrange(m):
yield players[-1], players[i]
for j in xrange(1, n/2):
yield players[(i+j)%m], players[(i-j)%m]

def print_matches(players):
for line in zip(*matches(players)):
print ' '.join(line)

def tournament(players, courts, nrounds=None):

players: list of players
courts: list of courts
nrounds: number of rounds needed or 

if nrounds is None:
rounds = count(1)
else:
rounds = xrange(1, nrounds + 1)
opponents = defaultdict(list)
courts = courts[:len(players)/2]
get_match = matches(players).next
try:
for round in rounds:
print '-'*10
print 'Round', round
for court in courts:
p1, p2 = get_match()
print 'Court %s: %s - %s' % (court, p1, p2)
except StopIteration:
print All matches played


Example:

 players = ['Ann', 'Bea', 'Clo', 'Dee', 'Evi', 'Fae', 'Gil', 'Haz']
 courts = ['One', 'Two', 'Three']
 tournament(players, courts, 4)
--
Round 1
Court One: Haz - Ann
Court Two: Bea - Gil
Court Three: Clo - Fae
--
Round 2
Court One: Dee - Evi
Court Two: Haz - Bea
Court Three: Clo - Ann
--
Round 3
Court One: Dee - Gil
Court Two: Evi - Fae
Court Three: Haz - Clo
--
Round 4
Court One: Dee - Bea
Court Two: Evi - Ann
Court Three: Fae - Gil

HTH

-- 
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-07 Thread MRAB

John Yeung wrote:

On May 7, 12:30 am, Ross ross.j...@gmail.com wrote:

If I were to set up a dictionary that counted players used in the bye
list and only allowed players to be added to the bye list if they were
within 2 of the least used player, would this be a good approach for
managing bye selection or would using a dictionary in this manner be
unnecessary/redundant?


I certainly have not proved it, but I think you don't need to resort
to anything fancy if you are OK with the maximum byes being within two
of the minimum byes.  (Maybe this needs to be larger with larger
numbers of players.)  Try using your original shuffle but instead of
selecting matches to throw away each week, just use the matches you
need (to fill up the courts) and pick up where you left off the next
week.  For example, with 10 players, each round ideally consists of
five matches.  If you only have four courts, don't throw away the
fifth match; save it as the first match next week.

To be honest, I didn't look too carefully at your original shuffle.
It may be good enough.  It's a little different than the standard
rotation as presented on Wikipedia:

  http://en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm

The one on Wikipedia happened to pass my casual tests with no more
than a 2-bye difference between the most-played and least-played
players, and didn't run into the problem of scheduling the same player
for two matches the same week.  But I have to stress I only tried a
few starting values, which all worked; I didn't try to break it, or
run an extensive battery of tests.


It might be an idea to run an exhaustive test on small, but not too
small, values in order to see whether the minimum difference can, in
fact, be one. If the minimum difference turns out to be two then you
might as well stick to a simple algorithm, as long as its minimum
difference is two.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-07 Thread Ross
On May 7, 1:11 am, John Yeung gallium.arsen...@gmail.com wrote:
 On May 7, 12:30 am, Ross ross.j...@gmail.com wrote:



  If I were to set up a dictionary that counted players used in the bye
  list and only allowed players to be added to the bye list if they were
  within 2 of the least used player, would this be a good approach for
  managing bye selection or would using a dictionary in this manner be
  unnecessary/redundant?

 I certainly have not proved it, but I think you don't need to resort
 to anything fancy if you are OK with the maximum byes being within two
 of the minimum byes.  (Maybe this needs to be larger with larger
 numbers of players.)  Try using your original shuffle but instead of
 selecting matches to throw away each week, just use the matches you
 need (to fill up the courts) and pick up where you left off the next
 week.  For example, with 10 players, each round ideally consists of
 five matches.  If you only have four courts, don't throw away the
 fifth match; save it as the first match next week.

 To be honest, I didn't look too carefully at your original shuffle.
 It may be good enough.  It's a little different than the standard
 rotation as presented on Wikipedia:

  http://en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm

 The one on Wikipedia happened to pass my casual tests with no more
 than a 2-bye difference between the most-played and least-played
 players, and didn't run into the problem of scheduling the same player
 for two matches the same week.  But I have to stress I only tried a
 few starting values, which all worked; I didn't try to break it, or
 run an extensive battery of tests.

 John

John,
   I really appreciate your help with this problem. Thanks to your
suggestions, I've managed to solve the problem. Here's what I did: I
used my original round_robin generator to generate each week. I then
took every week and chained them all together end to end. Then,
depending on how many courts are available, I can select that many
tuples at a time from the list. If you go in order, the discrepancy
between the player with the least amount of byes and the greatest
amount of byes is only 1. If you can make it exactly all the way
through a cycle, there will be no discrepancy. Anyways, I've done all
this by hand and it works so now I'm going to go ahead and code it up.
Again, thanks for your help.

-Ross
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-07 Thread John Yeung
On May 7, 8:32 pm, Ross ross.j...@gmail.com wrote:
 I've managed to solve the problem. If you go in
 order, the discrepancy between the player with the
 least amount of byes and the greatest amount of byes
 is only 1.

I don't mean to rain on your parade, but that's not the case for all
values.  For example, with 7 players and only 1 or 2 courts, there
will be weeks in the middle where the bye-difference is 2.

This behavior is present in both your shuffle and the standard one in
Wikipedia.

Ultimately, as it pertains to your physical tennis scheduling with
actual courts and actual players, you may never encounter the
imbalance.  But as a math problem, it's still not solved.  (Someone
may have solved it or proved it insoluble, but obviously I am not
aware of such a proof, because otherwise I would have presented it
already.)

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread MRAB

John Yeung wrote:

On May 5, 11:37 pm, Ross ross.j...@gmail.com wrote:


On May 5, 10:33 am, MRAB goo...@mrabarnett.plus.com wrote:


Here's my approach (incomplete):

FYI... I was testing your code further and discovered a strange
outcome... when there are 16 people for 7 courts, every 7th
round your code produces 4 byes instead of the correct 2 byes.


Well, MRAB did say his was incomplete, and it's significantly shorter
and cleaner than mine.

Mine has even weirder-looking behavior at 16 players on 7 courts, but
I think it's because mine tries harder to keep things balanced.  After
a few rounds, the inequalities start to build up, and my routine picks
some people more often to catch up, but it doesn't prevent the same
person from being scheduled for multiple matches the same week.  There
may also be other, more subtle ways mine is broken.

It also may be that the problem is inherently unsolvable for some
values.  (I'm still waiting for someone with sufficient math ability
to swoop in and either provide a way that works for all values, or
confirm that there are just some unavoidable pathological cases.)


I'm not sure that all the requirements can be met.

I have the feeling that if the number of rounds is restricted then the
difference between the minimum and maximum number of byes could be 2
because of the requirement that players shouldn't play each other more
than once, meaning that the players have to be shuffled around a bit, so
a player might play a week earlier or later than would otherwise be the
case.

If every possible combination is done (everyone plays everyone else)
then the number of byes would be the same for all, otherwise the
difference could be 2, not 1. I think! :-)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread John Yeung
On May 5, 10:49 am, Ross ross.j...@gmail.com wrote:
 I'm interested to see what you did. From your description,
 it sounds like I've tried what you've done, but when I
 implemented my version, it took minutes to evaluate for
 bigger numbers. If that isn't the case with yours, I'd be
 interested in seeing your implementation.

I don't know how big your bigger numbers are, but this should run in
a reasonable time.  It helps if you are using Python 2.6.  If not, you
should go on-line to the itertools docs to get the pure-Python
equivalent for itertools.combinations.

Since no matches are thrown away, the byes are expressed simply as a
list of players that have to sit out for the week.

A couple of the lines are on the longish side, so beware of wrapping
from the browser/newsreader.

# Let's just try choosing from the possible combinations, each week
# scheduling those who have played the least or waited the longest.

import itertools

class Player(object):
def __init__(self, id):
self.id = id
self.played = []
self.latency = 0

def __str__(self):
str(self.id)

def __cmp__(self, other):
if len(self.played) != len(other.played):
return len(self.played) - len(other.played)
return other.latency - self.latency # select longer latency
first

def flattened(listOfLists):
return list(itertools.chain(*listOfLists))

def pairings(players):
idlist = range(players)
playerlist = [Player(i) for i in idlist]
matchlist = list(itertools.combinations(idlist, 2))
while matchlist:
found = False
playerlist.sort()
for i in range(players - 1):
for j in range(i + 1, players):
candidate = tuple(sorted((playerlist[i].id, playerlist
[j].id)))
if candidate in matchlist:
yield matchlist.pop(matchlist.index(candidate))
for p in playerlist:
if p.id == candidate[0]:
p.played.append(candidate[1])
p.latency = 0
elif p.id == candidate[1]:
p.played.append(candidate[0])
p.latency = 0
else:
p.latency += 1
found = True
break
if found: break

def schedule(players, weeks, courts):
playerlist = range(players)
matchlist = list(pairings(players))
cap = min(courts, players // 2)
start = 0
for week in range(weeks):
matches = matchlist[start:start + cap]
byes = set(playerlist) - set(flattened(matches))
print matches, list(byes)
start += cap
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread John Yeung
On May 6, 3:29 am, MRAB goo...@mrabarnett.plus.com wrote:

 I have the feeling that if the number of rounds is restricted then the
 difference between the minimum and maximum number of byes could be 2
 because of the requirement that players shouldn't play each other more
 than once, meaning that the players have to be shuffled around a bit, so
 a player might play a week earlier or later than would otherwise be the
 case.

This is the feeling that I am getting also.  All my efforts to keep
everything as balanced as possible at all times (to be ready for the
season to end suddenly at any time) result in messy jams that could
otherwise be alleviated if I allowed temporary imbalances, knowing
that there are more weeks later to make them up.

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread Ross
On May 6, 3:14 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 6, 3:29 am, MRAB goo...@mrabarnett.plus.com wrote:

  I have the feeling that if the number of rounds is restricted then the
  difference between the minimum and maximum number of byes could be 2
  because of the requirement that players shouldn't play each other more
  than once, meaning that the players have to be shuffled around a bit, so
  a player might play a week earlier or later than would otherwise be the
  case.

 This is the feeling that I am getting also.  All my efforts to keep
 everything as balanced as possible at all times (to be ready for the
 season to end suddenly at any time) result in messy jams that could
 otherwise be alleviated if I allowed temporary imbalances, knowing
 that there are more weeks later to make them up.

 John

If I were to set up a dictionary that counted players used in the bye
list and only allowed players to be added to the bye list if they were
within 2 of the least used player, would this be a good approach for
managing bye selection or would using a dictionary in this manner be
unnecessary/redundant?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread Ross
On May 6, 3:14 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 6, 3:29 am, MRAB goo...@mrabarnett.plus.com wrote:

  I have the feeling that if the number of rounds is restricted then the
  difference between the minimum and maximum number of byes could be 2
  because of the requirement that players shouldn't play each other more
  than once, meaning that the players have to be shuffled around a bit, so
  a player might play a week earlier or later than would otherwise be the
  case.

 This is the feeling that I am getting also.  All my efforts to keep
 everything as balanced as possible at all times (to be ready for the
 season to end suddenly at any time) result in messy jams that could
 otherwise be alleviated if I allowed temporary imbalances, knowing
 that there are more weeks later to make them up.

 John

If I were to set up a dictionary that counted players used in the bye
list and only allowed players to be added to the bye list if they were
within 2 of the least used player, would this be a good approach for
managing bye selection or would using a dictionary in this manner be
unnecessary/redundant?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread Ross
On May 6, 3:14 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 6, 3:29 am, MRAB goo...@mrabarnett.plus.com wrote:

  I have the feeling that if the number of rounds is restricted then the
  difference between the minimum and maximum number of byes could be 2
  because of the requirement that players shouldn't play each other more
  than once, meaning that the players have to be shuffled around a bit, so
  a player might play a week earlier or later than would otherwise be the
  case.

 This is the feeling that I am getting also.  All my efforts to keep
 everything as balanced as possible at all times (to be ready for the
 season to end suddenly at any time) result in messy jams that could
 otherwise be alleviated if I allowed temporary imbalances, knowing
 that there are more weeks later to make them up.

 John

If I were to set up a dictionary that counted players used in the bye
list and only allowed players to be added to the bye list if they were
within 2 of the least used player, would this be a good approach for
managing bye selection or would using a dictionary in this manner be
unnecessary/redundant?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-06 Thread John Yeung
On May 7, 12:30 am, Ross ross.j...@gmail.com wrote:

 If I were to set up a dictionary that counted players used in the bye
 list and only allowed players to be added to the bye list if they were
 within 2 of the least used player, would this be a good approach for
 managing bye selection or would using a dictionary in this manner be
 unnecessary/redundant?

I certainly have not proved it, but I think you don't need to resort
to anything fancy if you are OK with the maximum byes being within two
of the minimum byes.  (Maybe this needs to be larger with larger
numbers of players.)  Try using your original shuffle but instead of
selecting matches to throw away each week, just use the matches you
need (to fill up the courts) and pick up where you left off the next
week.  For example, with 10 players, each round ideally consists of
five matches.  If you only have four courts, don't throw away the
fifth match; save it as the first match next week.

To be honest, I didn't look too carefully at your original shuffle.
It may be good enough.  It's a little different than the standard
rotation as presented on Wikipedia:

  http://en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm

The one on Wikipedia happened to pass my casual tests with no more
than a 2-bye difference between the most-played and least-played
players, and didn't run into the problem of scheduling the same player
for two matches the same week.  But I have to stress I only tried a
few starting values, which all worked; I didn't try to break it, or
run an extensive battery of tests.

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread John Yeung
On May 5, 1:12 am, John Yeung gallium.arsen...@gmail.com wrote:

 [...] the problem may require bigger guns (either much better
 math or much more sophisticated programming).

Yes, I'm responding to myself.

Well, I went ahead with the approach I mentioned earlier, generating
all possible matches and then selecting among them as needed to fill
up the courts, trying to keep the number of matches played by each
player as fair as possible.  (I should mention that this, or something
similar, was suggested earlier by someone else in a different thread,
in response to the same question by the same OP.)

I did use bigger guns (mainly a class for player objects, with
custom __cmp__ method), but still didn't do anything with doubles.

I haven't tested it much, but I'll post it if anyone's interested.
(That way people can pick on me instead of the OP. ;)

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread Ross
On May 5, 12:32 am, John Yeung gallium.arsen...@gmail.com wrote:
 On May 5, 1:12 am, John Yeung gallium.arsen...@gmail.com wrote:

  [...] the problem may require bigger guns (either much better
  math or much more sophisticated programming).

 Yes, I'm responding to myself.

 Well, I went ahead with the approach I mentioned earlier, generating
 all possible matches and then selecting among them as needed to fill
 up the courts, trying to keep the number of matches played by each
 player as fair as possible.  (I should mention that this, or something
 similar, was suggested earlier by someone else in a different thread,
 in response to the same question by the same OP.)

 I did use bigger guns (mainly a class for player objects, with
 custom __cmp__ method), but still didn't do anything with doubles.

 I haven't tested it much, but I'll post it if anyone's interested.
 (That way people can pick on me instead of the OP. ;)

 John

I'm interested to see what you did. From your description, it sounds
like I've tried what you've done, but when I implemented my version,
it took minutes to evaluate for bigger numbers. If that isn't the case
with yours, I'd be interested in seeing your implementation.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread MRAB

Ross wrote:

On May 5, 12:32 am, John Yeung gallium.arsen...@gmail.com wrote:

On May 5, 1:12 am, John Yeung gallium.arsen...@gmail.com wrote:


[...] the problem may require bigger guns (either much better
math or much more sophisticated programming).

Yes, I'm responding to myself.

Well, I went ahead with the approach I mentioned earlier, generating
all possible matches and then selecting among them as needed to fill
up the courts, trying to keep the number of matches played by each
player as fair as possible.  (I should mention that this, or something
similar, was suggested earlier by someone else in a different thread,
in response to the same question by the same OP.)

I did use bigger guns (mainly a class for player objects, with
custom __cmp__ method), but still didn't do anything with doubles.

I haven't tested it much, but I'll post it if anyone's interested.
(That way people can pick on me instead of the OP. ;)

John


I'm interested to see what you did. From your description, it sounds
like I've tried what you've done, but when I implemented my version,
it took minutes to evaluate for bigger numbers. If that isn't the case
with yours, I'd be interested in seeing your implementation.


Here's my approach (incomplete):

def get_pair(player_list, played):
for first in range(len(player_list)):
player_1 = player_list[first]
for second in range(first + 1, len(player_list)):
player_2 = player_list[second]
pair = player_1, player_2
sorted_pair = tuple(sorted(pair))
if sorted_pair not in played:
played.add(sorted_pair)
del player_list[second]
del player_list[first]
return pair
return None

def round_robin(player_list, courts, played):
playing = []
for c in range(courts):
pair = get_pair(player_list, played)
if pair is None:
break
playing.append(pair)
byes = player_list[:]
player_list[:] = byes + [player for pair in playing for player in pair]
yield playing, byes

def test_round_robin(players, rounds, courts, doubles=False):
player_list = range(players)
played = set()
for r in range(rounds):
for playing, byes in round_robin(player_list, courts, played):
print playing, byes

--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread Ross
On May 5, 1:33 pm, MRAB goo...@mrabarnett.plus.com wrote:
 Ross wrote:
  On May 5, 12:32 am, John Yeung gallium.arsen...@gmail.com wrote:
  On May 5, 1:12 am, John Yeung gallium.arsen...@gmail.com wrote:

  [...] the problem may require bigger guns (either much better
  math or much more sophisticated programming).
  Yes, I'm responding to myself.

  Well, I went ahead with the approach I mentioned earlier, generating
  all possible matches and then selecting among them as needed to fill
  up the courts, trying to keep the number of matches played by each
  player as fair as possible.  (I should mention that this, or something
  similar, was suggested earlier by someone else in a different thread,
  in response to the same question by the same OP.)

  I did use bigger guns (mainly a class for player objects, with
  custom __cmp__ method), but still didn't do anything with doubles.

  I haven't tested it much, but I'll post it if anyone's interested.
  (That way people can pick on me instead of the OP. ;)

  John

  I'm interested to see what you did. From your description, it sounds
  like I've tried what you've done, but when I implemented my version,
  it took minutes to evaluate for bigger numbers. If that isn't the case
  with yours, I'd be interested in seeing your implementation.

 Here's my approach (incomplete):

 def get_pair(player_list, played):
      for first in range(len(player_list)):
          player_1 = player_list[first]
          for second in range(first + 1, len(player_list)):
              player_2 = player_list[second]
              pair = player_1, player_2
              sorted_pair = tuple(sorted(pair))
              if sorted_pair not in played:
                  played.add(sorted_pair)
                  del player_list[second]
                  del player_list[first]
                  return pair
      return None

 def round_robin(player_list, courts, played):
      playing = []
      for c in range(courts):
          pair = get_pair(player_list, played)
          if pair is None:
              break
          playing.append(pair)
      byes = player_list[:]
      player_list[:] = byes + [player for pair in playing for player in pair]
      yield playing, byes

 def test_round_robin(players, rounds, courts, doubles=False):
      player_list = range(players)
      played = set()
      for r in range(rounds):
          for playing, byes in round_robin(player_list, courts, played):
              print playing, byes- Hide quoted text -

 - Show quoted text -

Looks like somewhat of an improvement, although the bye distribution
is still slightly lopsided. For example, in a singles league with 12
players, 12 rounds, and 4 courts, The first player had at least 2 less
byes than every other player and 3 less byes than the players with the
most number of byes. Thanks for your input though...I'll look into how
I can improve upon it.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread Ross
On May 5, 10:33 am, MRAB goo...@mrabarnett.plus.com wrote:
 Ross wrote:
  On May 5, 12:32 am, John Yeung gallium.arsen...@gmail.com wrote:
  On May 5, 1:12 am, John Yeung gallium.arsen...@gmail.com wrote:

  [...] the problem may require bigger guns (either much better
  math or much more sophisticated programming).
  Yes, I'm responding to myself.

  Well, I went ahead with the approach I mentioned earlier, generating
  all possible matches and then selecting among them as needed to fill
  up the courts, trying to keep the number of matches played by each
  player as fair as possible.  (I should mention that this, or something
  similar, was suggested earlier by someone else in a different thread,
  in response to the same question by the same OP.)

  I did use bigger guns (mainly a class for player objects, with
  custom __cmp__ method), but still didn't do anything with doubles.

  I haven't tested it much, but I'll post it if anyone's interested.
  (That way people can pick on me instead of the OP. ;)

  John

  I'm interested to see what you did. From your description, it sounds
  like I've tried what you've done, but when I implemented my version,
  it took minutes to evaluate for bigger numbers. If that isn't the case
  with yours, I'd be interested in seeing your implementation.

 Here's my approach (incomplete):

 def get_pair(player_list, played):
      for first in range(len(player_list)):
          player_1 = player_list[first]
          for second in range(first + 1, len(player_list)):
              player_2 = player_list[second]
              pair = player_1, player_2
              sorted_pair = tuple(sorted(pair))
              if sorted_pair not in played:
                  played.add(sorted_pair)
                  del player_list[second]
                  del player_list[first]
                  return pair
      return None

 def round_robin(player_list, courts, played):
      playing = []
      for c in range(courts):
          pair = get_pair(player_list, played)
          if pair is None:
              break
          playing.append(pair)
      byes = player_list[:]
      player_list[:] = byes + [player for pair in playing for player in pair]
      yield playing, byes

 def test_round_robin(players, rounds, courts, doubles=False):
      player_list = range(players)
      played = set()
      for r in range(rounds):
          for playing, byes in round_robin(player_list, courts, played):
              print playing, byes

FYI... I was testing your code further and discovered a strange
outcome... when there are 16 people for 7 courts, every 7th round your
code produces 4 byes instead of the correct 2 byes.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-05 Thread John Yeung
On May 5, 11:37 pm, Ross ross.j...@gmail.com wrote:

 On May 5, 10:33 am, MRAB goo...@mrabarnett.plus.com wrote:

  Here's my approach (incomplete):

 FYI... I was testing your code further and discovered a strange
 outcome... when there are 16 people for 7 courts, every 7th
 round your code produces 4 byes instead of the correct 2 byes.

Well, MRAB did say his was incomplete, and it's significantly shorter
and cleaner than mine.

Mine has even weirder-looking behavior at 16 players on 7 courts, but
I think it's because mine tries harder to keep things balanced.  After
a few rounds, the inequalities start to build up, and my routine picks
some people more often to catch up, but it doesn't prevent the same
person from being scheduled for multiple matches the same week.  There
may also be other, more subtle ways mine is broken.

It also may be that the problem is inherently unsolvable for some
values.  (I'm still waiting for someone with sufficient math ability
to swoop in and either provide a way that works for all values, or
confirm that there are just some unavoidable pathological cases.)

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 3, 10:16 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 3, 11:29 pm, Chris Rebert c...@rebertia.com wrote:

  Probably not the cause of the problem, but where
  did the magic numbers 1.072 and 1.08 come from?

 It is perhaps not the most direct cause of the problem, in the sense
 that the magic numbers could take various values and the problem would
 still be there.  But the magic numbers appear to be used for
 spreading out bye selection, and that's broken.

 The extended slice as written will always pick the first element,
 since the step is guaranteed to be positive.  Since the first player
 (or None, when there are an odd number of players) stays put in the
 first position during the round_robin shuffle, that player will always
 be selected for a bye.

 Further, as written, the calculated number of byes has no bearing on
 the actual number of byes selected.

 I think what I would do is adjust the shuffling algorithm in such a
 way that everyone moves through the various positions in the list
 (would it be as simple as adding a shift at the end of
 round_robin???).  Then I could simply select the byes from one end of
 the list (with a regular slice instead of an extended slice).

 John

The magic numbers that everyone is wondering about are indeed used
for spreading out the bye selection and I got them by simply
calculating a line of best fit when plotting several courts: byes
ratios.

The byes = #whatever in my code calculate the number of tuples that
need to be placed in the bye_list.

At first glance, the suggestion of adding a simple shift at the end of
round_robin doesn't seem to work since round_robin already shifts
everything except for the first position already. Please correct me if
I'm wrong because you might have been suggesting something different.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 4, 7:01 am, Ross ross.j...@gmail.com wrote:
 On May 3, 10:16 pm, John Yeung gallium.arsen...@gmail.com wrote:



  On May 3, 11:29 pm, Chris Rebert c...@rebertia.com wrote:

   Probably not the cause of the problem, but where
   did the magic numbers 1.072 and 1.08 come from?

  It is perhaps not the most direct cause of the problem, in the sense
  that the magic numbers could take various values and the problem would
  still be there.  But the magic numbers appear to be used for
  spreading out bye selection, and that's broken.

  The extended slice as written will always pick the first element,
  since the step is guaranteed to be positive.  Since the first player
  (or None, when there are an odd number of players) stays put in the
  first position during the round_robin shuffle, that player will always
  be selected for a bye.

  Further, as written, the calculated number of byes has no bearing on
  the actual number of byes selected.

  I think what I would do is adjust the shuffling algorithm in such a
  way that everyone moves through the various positions in the list
  (would it be as simple as adding a shift at the end of
  round_robin???).  Then I could simply select the byes from one end of
  the list (with a regular slice instead of an extended slice).

  John

 The magic numbers that everyone is wondering about are indeed used
 for spreading out the bye selection and I got them by simply
 calculating a line of best fit when plotting several courts: byes
 ratios.

 The byes = #whatever in my code calculate the number of tuples that
 need to be placed in the bye_list.

 At first glance, the suggestion of adding a simple shift at the end of
 round_robin doesn't seem to work since round_robin already shifts
 everything except for the first position already. Please correct me if
 I'm wrong because you might have been suggesting something different.

And also, as you all have pointed out, my inclusion of

 def test_round_robin(players, rounds, courts, doubles = False):
 players = range(players)
 for week in round_robin(players,rounds,courts):

should have been

 def test_round_robin(players, rounds, courts, doubles = False):
 players = range(players)
 for week in round_robin(players,rounds):

I forgot to erase that extra parameter when I was playing around with
my code.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 3, 8:29 pm, John Machin sjmac...@lexicon.net wrote:
 On May 4, 12:36 pm, Ross ross.j...@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 

Re: Code works fine except...

2009-05-04 Thread Aahz
In article 8d4ec1df-dddb-469a-99a1-695152db7...@n4g2000vba.googlegroups.com,
Ross  ross.j...@gmail.com wrote:

def test_round_robin(players, rounds, courts, doubles = False):
players = range(players)
for week in round_robin(players,rounds,courts):
   if doubles == True:
   doubles_week = len(week)/2.0
   byes = doubles_week - courts

Side note: thou shalt indent four spaces, no more, no fewer

For more info, see PEP 8.
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

It is easier to optimize correct code than to correct optimized code.
--Bill Harlan
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 4, 12:15 pm, a...@pythoncraft.com (Aahz) wrote:
 In article 8d4ec1df-dddb-469a-99a1-695152db7...@n4g2000vba.googlegroups.com,

 Ross  ross.j...@gmail.com wrote:

 def test_round_robin(players, rounds, courts, doubles = False):
     players = range(players)
     for week in round_robin(players,rounds,courts):
         if doubles == True:
                 doubles_week = len(week)/2.0
                 byes = doubles_week - courts

 Side note: thou shalt indent four spaces, no more, no fewer

 For more info, see PEP 8.
 --
 Aahz (a...@pythoncraft.com)           *        http://www.pythoncraft.com/

 It is easier to optimize correct code than to correct optimized code.
 --Bill Harlan

Yes... I know this. Unfortunately, copy/pasting my code from the IDE
into the google group messes with indentations.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread John Yeung
On May 4, 10:01 am, Ross ross.j...@gmail.com wrote:
 The magic numbers that everyone is wondering about are
 indeed used for spreading out the bye selection and I got
 them by simply calculating a line of best fit when plotting
 several courts: byes ratios.

But that doesn't really help you.  When you do seq[::step], step is
evaluated once and used for the whole extended slice.  So in almost
all cases that you are likely to encounter, step is 2, so you'll get
seq[0], seq[2], seq[4], etc.  Even if step is some other positive
number, seq[0] will always be chosen.

 The byes = #whatever in my code calculate the number of
 tuples that need to be placed in the bye_list.

Fine, but that's not the number of byes that you put into bye_list.

 At first glance, the suggestion of adding a simple shift
 at the end of round_robin doesn't seem to work since
 round_robin already shifts everything except for the first
 position already. Please correct me if I'm wrong because
 you might have been suggesting something different.

If you read my post carefully, you would see that you HAVE to do
something about the first player always being stuck in the first
spot.  Either move him around, or select your byes differently.

That said, I've played around with the shuffling a bit, and it does
seem to be pretty tricky to get it to work for the general case where
there is no prior knowledge of how many players and courts you will
have.

I can't shake the feeling that someone good at math will be able to
figure out something elegant; but if left to my own devices, I am
starting to lean toward just generating all the possible matches and
somehow picking from them as needed to fill the courts, trying to keep
the number of matches played by each player as close to equal as
possible, and trying to keep the waiting times approximately equal as
well.

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 4, 7:59 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 4, 10:01 am, Ross ross.j...@gmail.com wrote:

  The magic numbers that everyone is wondering about are
  indeed used for spreading out the bye selection and I got
  them by simply calculating a line of best fit when plotting
  several courts: byes ratios.

 But that doesn't really help you.  When you do seq[::step], step is
 evaluated once and used for the whole extended slice.  So in almost
 all cases that you are likely to encounter, step is 2, so you'll get
 seq[0], seq[2], seq[4], etc.  Even if step is some other positive
 number, seq[0] will always be chosen.

  The byes = #whatever in my code calculate the number of
  tuples that need to be placed in the bye_list.

 Fine, but that's not the number of byes that you put into bye_list.

  At first glance, the suggestion of adding a simple shift
  at the end of round_robin doesn't seem to work since
  round_robin already shifts everything except for the first
  position already. Please correct me if I'm wrong because
  you might have been suggesting something different.

 If you read my post carefully, you would see that you HAVE to do
 something about the first player always being stuck in the first
 spot.  Either move him around, or select your byes differently.

 That said, I've played around with the shuffling a bit, and it does
 seem to be pretty tricky to get it to work for the general case where
 there is no prior knowledge of how many players and courts you will
 have.

 I can't shake the feeling that someone good at math will be able to
 figure out something elegant; but if left to my own devices, I am
 starting to lean toward just generating all the possible matches and
 somehow picking from them as needed to fill the courts, trying to keep
 the number of matches played by each player as close to equal as
 possible, and trying to keep the waiting times approximately equal as
 well.

 John

But that doesn't really help you.  When you do seq[::step], step is
evaluated once and used for the whole extended slice.  So in almost
all cases that you are likely to encounter, step is 2, so you'll get
seq[0], seq[2], seq[4], etc.  Even if step is some other positive
number, seq[0] will always be chosen.

It's not true that in almost all cases the step is 2. How that is
evaluated directly depends on the number of available courts. Anyways,
you're right that seq[0] is always evaluated. That's why my algorithm
works fine when there are odd numbers of players in a league. But if
you will notice, my original question was how I could ADD TO or AMMEND
my current code to account for even number of players. I have used an
algorithm that comes up with all possible pairings and then randomly
puts people together each week and places players in a bye list
according to how many times they've previously been in the bye list
but since I was dealing with random permutations, the algorithm took
minutes to evaluate when there were more than 10 players in the
league.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread John Yeung
On May 4, 8:56 pm, Ross ross.j...@gmail.com wrote:

 Anyways, you're right that seq[0] is always evaluated.
 That's why my algorithm works fine when there are odd
 numbers of players in a league.

It doesn't work fine for all odd numbers of players.  For example, 15
players on 3 courts should result in 5 byes.  But what actually
happens with your code is that you get 4 byes or 8 byes, depending on
whether you've got floating-point division enabled.

So the way you are selecting byes does not even guarantee that you'll
allocate the correct number of active matches for the number of
courts, and this is due to the fact that the extended slice is too
coarse a tool for the task.  Now, it may be that for you, the number
of players and courts is always within a confined range such that
extended slicing and your magic constants will work.  That's fine for
you, but we weren't given that information.

I haven't even begun to look at what happens for doubles.

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread Ross
On May 4, 7:33 pm, John Yeung gallium.arsen...@gmail.com wrote:
 On May 4, 8:56 pm, Ross ross.j...@gmail.com wrote:

  Anyways, you're right that seq[0] is always evaluated.
  That's why my algorithm works fine when there are odd
  numbers of players in a league.

 It doesn't work fine for all odd numbers of players.  For example, 15
 players on 3 courts should result in 5 byes.  But what actually
 happens with your code is that you get 4 byes or 8 byes, depending on
 whether you've got floating-point division enabled.

 So the way you are selecting byes does not even guarantee that you'll
 allocate the correct number of active matches for the number of
 courts, and this is due to the fact that the extended slice is too
 coarse a tool for the task.  Now, it may be that for you, the number
 of players and courts is always within a confined range such that
 extended slicing and your magic constants will work.  That's fine for
 you, but we weren't given that information.

 I haven't even begun to look at what happens for doubles.

 John

You're right... I only tested cases when number of people playing
outnumbered the number of byes that week. Anyways, I'm new to
programming and this has been a good learning experience. Next time
around, I'll be sure to thoroughly comment my code before I ask for
help on it. I really appreciate all the help that you've offered so
far. Right now, I'm debating whether I should try to reinvent the
round_robin generator part of the code or whether there still might be
a way to shuffle the results of the generated output so that I can
slice it effectively.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-04 Thread John Yeung
On May 4, 11:01 pm, Ross ross.j...@gmail.com wrote:
 Anyways, I'm new to
 programming and this has been a good learning experience.

I'm glad that you've been trying, and seem to be sticking it out
despite sometimes getting negative feedback here.

 Next time around, I'll be sure to thoroughly comment
 my code before I ask for help on it.

The best documentation, especially for a language like Python, is
simply logical variable names and sensible conventions.  I bring this
up because I'm wary of the word thoroughly.  When you're dealing
with experts, it's actually best to use inline comments sparingly;
they can figure out what code does.  The overall problem description
at the top is important, as well as explanation of magic numbers and
such.

 I really appreciate all the help that you've offered so far.

You're welcome.  I'm not sure how much I've helped, especially as I'm
frankly not one of the stronger programmers here.

 Right now, I'm debating whether I should try to reinvent
 the round_robin generator part of the code or whether
 there still might be a way to shuffle the results of the
 generated output so that I can slice it effectively.

If you are going to typically have roughly enough courts for your
players (as implied by your test data), then maybe there's still a
chance for using extended slicing.  Just make sure you don't always
pick the first element.  If the number of players and the number of
courts can vary wildly, and won't always match up at least sort of
nicely, then the problem may require bigger guns (either much better
math or much more sophisticated programming).

John
--
http://mail.python.org/mailman/listinfo/python-list


Code works fine except...

2009-05-03 Thread Ross
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)
for week in round_robin(players,rounds,courts):
if doubles == True:
doubles_week = len(week)/2.0
byes = doubles_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]
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
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-03 Thread Chris Rebert
On Sun, May 3, 2009 at 7:36 PM, Ross ross.j...@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)
    for week in round_robin(players,rounds,courts):
            if doubles == True:
                    doubles_week = len(week)/2.0
                    byes = doubles_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]
                    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

Probably not the cause of the problem, but where did the magic numbers
1.072 and 1.08 come from?

Cheers,
Chris
-- 
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-03 Thread John Machin
On May 4, 12:36 pm, Ross ross.j...@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

--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-03 Thread John Yeung
On May 3, 10:36 pm, Ross ross.j...@gmail.com wrote:

 def round_robin(players, rounds):
[snip]


 def test_round_robin(players, rounds, courts, doubles = False):
     players = range(players)
     for week in round_robin(players,rounds,courts):
[snip]

First things first:  I take it the call to round_robin is only
supposed to take two parameters?  Or do you have a version that takes
3?

John
--
http://mail.python.org/mailman/listinfo/python-list


Re: Code works fine except...

2009-05-03 Thread John Yeung
On May 3, 11:29 pm, Chris Rebert c...@rebertia.com wrote:

 Probably not the cause of the problem, but where
 did the magic numbers 1.072 and 1.08 come from?

It is perhaps not the most direct cause of the problem, in the sense
that the magic numbers could take various values and the problem would
still be there.  But the magic numbers appear to be used for
spreading out bye selection, and that's broken.

The extended slice as written will always pick the first element,
since the step is guaranteed to be positive.  Since the first player
(or None, when there are an odd number of players) stays put in the
first position during the round_robin shuffle, that player will always
be selected for a bye.

Further, as written, the calculated number of byes has no bearing on
the actual number of byes selected.

I think what I would do is adjust the shuffling algorithm in such a
way that everyone moves through the various positions in the list
(would it be as simple as adding a shift at the end of
round_robin???).  Then I could simply select the byes from one end of
the list (with a regular slice instead of an extended slice).

John
--
http://mail.python.org/mailman/listinfo/python-list