Hello Martin, again thanks for your endeavour, ist tought me to really think deeply how to specify my task fort he Python language. Before I start to work with your "heavy" piece of code for a beginner below I like to make the following statements:
1. my task is to create lists or tupleS (whichever works best) containing 3 letters, later to be assigned names, in unique sequences. 2. My first approach with pairs like 'a b', 'a c',..... does not work with itertools.combinations(s, 3): Although, it produces lists/tuples with 3 pairs there are 4 letters in each list/tuple whereas I need only 3. 3. Therfore, I'am working with single letters creating lists/tuples with 3 letters: ('a', 'b', 'c'), ('a','b','d')........ Using all 26 letters of the alphabet would correspond to Problem A: Impossible to handle. Using only 15 letters would already create 455 lists/tuples. So I am using 9 letters which is practical for one letter or name can be combined with 2 others 5 times or on 5 days, each letter/name can occur only once a day. The 9 letters produce 84 lists/tuples. But if I am isolating lists/tuple with unique sequences by hand I am left with 15 lists/tuples but with a uneven distrubution of the 9 letters: a 8 b 5 c 6 d 5 e 6 f 6 g 4 h 4 i 4 This variance gets the smaller the more letters are used. 4. I have come to the conclusion that my task is too mathematical for itertools. I hope I can be successfull with your code below although it will me take time to comprehend it. Sorry for this long text, regards, Marcus. -----Ursprüngliche Nachricht----- Von: Martin A. Brown [mailto:mar...@linux-ip.net] Gesendet: Dienstag, 22. September 2015 03:10 An: marcus lütolf <marcus.luet...@bluewin.ch> Cc: tutor@python.org Betreff: Re: [Tutor] Creating lists with 3 (later4) items occuring only once Marcus, I have more questions for you, as well as a possible solution (though it's a bit more verbose than I would have liked to offer). Question: Problem A: Are you looking to identify the complete set of possible options for constructing the triples of pairs? Problem B: Are you looking only to construct one set that satisfies the problem? [see my lousy solution] You may observe that the question I ask is quite similar to the question asked by Francesco [0]. If you are asking about the complete set of possible options (Problem A), then I submit to you that you are asking a mathematical question, not a Python question. If that's the case, perhaps you should look further into the Steiner system and/or ask again on the list. If you are asking about finding an individual solution satisfying the constraints, I submit to you that either my approach or Francesco's approach could work for you. If that's the case, then using random.sample may offer you some help. See my sample, below--it should work on Python 2.x or Python 3.x. Comments: * There are rules in your system about when a player can play again. The rules were not fully clear to me, so I allowed players to be selecteda second time, if there were no more players who had not already been chosen. * This program produces only one possible scenario for 7 rounds of 3 distinct, simultaneously played 2-player games. No player can play twice in the same round. (Simple arithmetic determines the minimum number of players.) If your question is Problem A, then I wonder if you know anybody who knows combinatorics? I do not. -Martin [0] https://mail.python.org/pipermail/tutor/2015-September/106820.html #! /usr/bin/python from __future__ import print_function import sys import string import random import logging logging.basicConfig(stream=sys.stderr, level=logging.INFO) logger = logging.getLogger() class NotEnoughPlayers(Exception): pass def choose_game_participants(players, pcount=2): '''returns a tuple of players for a single game ''' if len(players) < pcount: raise NotEnoughPlayers("not enough players, need %d, have only %d: %r" % (pcount, len(players), players)) game = tuple(sorted(random.sample(players, pcount))) return game def choose_match_games(players, pcount=2, gcount=3): '''returns a list of games where no player is duplicated ''' mcount = pcount * gcount if len(players) < mcount: raise NotEnoughPlayers("not enough players, need %d, have only %d: %r" % (mcount, len(players), players)) eligible_players = random.sample(players, mcount) match = list() while eligible_players: m = choose_game_participants(eligible_players, pcount) for x in m: eligible_players.remove(x) match.append(m) match.sort() # optional return match def generate_rounds(players, pcount, gcount, rcount): games = set() matches = list() mcount = pcount * gcount eligible_players = list(players) if mcount > len(eligible_players): raise NotEnoughPlayers("not enough players (%d) to guarantee %d %d-player games per match" % (len(eligible_players), gcount, pcount)) r = 1 while r <= rcount: try: proposed_match = choose_match_games(eligible_players, pcount, gcount) except NotEnoughPlayers: logger.info("adding %d additional players in round %d to meet minimum pool requirements", mcount, r) how_many = mcount - len(eligible_players) eligible_players.extend(random.sample(players, how_many)) continue already_played = games.intersection(set(proposed_match)) if already_played: logger.info("discarding %d %r because %r have already played", r, proposed_match, list(already_played)) continue else: games.update(proposed_match) matches.append(proposed_match) logger.info('Proposed match %r', proposed_match) for game in proposed_match: for player in game: eligible_players.remove(player) r = r + 1 return matches def log_match_info(matches, detail=False): for mnum, match in enumerate(matches, 1): logger.info("match summary %d: %r", mnum, match) for gnum, game in enumerate(match, 1): if not detail: continue logger.info("match detail %d, game %d: players %r", mnum, gnum, game) def log_match_summary(matches): log_match_info(matches, detail=False) def log_match_detail(matches): log_match_info(matches, detail=True) if __name__ == '__main__': players = list(string.ascii_uppercase) random.shuffle(players) # players = set('ABCDEFGHIJ') pcount = 2 # players per game gcount = 3 # games per match rcount = 7 # rounds (of matches) matches = generate_rounds(players, pcount, gcount, rcount) log_match_detail(matches) # -- end of file -- Martin A. Brown http://linux-ip.net/ --- Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft. https://www.avast.com/antivirus _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor