View Single Post
Old 12-15-2016, 09:15 PM   #163
Groundhog
Coordinator
 
Join Date: Dec 2003
Location: Sydney, Australia
Hey, the more the merrier as far as I'm concerned

Here's a snippet of what I put together actually nearly 12 months ago, checking the time stamp of the file. I've made a few small changes just now, but I haven't tested anything yet, so there may be typos/errors if you try run the below currently (just working out of notepad at the moment...)

The part that was frustrating me was the 'get_valid_game_days' method. There's nothing in the code below for this, but I spent an hour or so playing around on the python command line trying to solve this - basically, need to take a date range, and calculate all the valid game days within this range, grouped by week. The timedate library has some cool functionality that should make this possible, but I'll be darned if I could crack it - this was that "math-level" stuff I mentioned above that I struggle with.

For example, if Friday and Saturday were the only valid days, and the date range was for 4 weeks starting this week, the output of this method should be:

[[16/12/2016, 17/12/2016], [23/12/2016, 24/12/2016], [30/12/2016, 31/12/2016], [6/1/2017, 7/1/2017]]

As a rule I generally work with all dates as ordinal numbers - datetime objects have a .toordinal() method. I just trust it more, especially when writing to databases.

Code:
class ScheduleGen: def __init__(self, current_year=2016, season_start_month=9, season_start_day=30, season_end_month=3, season_end_day=28): self.current_year = current_year self.season_start_month = season_start_month def create_round_robin_schedule(self, team_ids=None, play_each_team=3, valid_days={'monday': False, 'tuesday': False, 'wednesday': False, 'thursday': False, 'friday': True, 'saturday': True, 'sunday': True}): matchups = self.generate_round_robin_matchups(teams=team_ids, play_each_team=play_each_team) valid_game_days = self.get_valid_game_days(valid_game_days=valid_days) def get_valid_game_days(self, valid_game_days): ''' Parameters: :valid_game_days: (dict) A dictionary of each day of the week and a True/False value. Returns: A list of all possible game days, in ordinal format. ''' # This is where I had trouble. What is needed here is to use the current_year/season_start_month/season_start_day, # the current_year+1/season_end_month/season_end_date, and the valid_game_days dictionary to compile a list of # all available dates, grouped in weeks (to ensure teams don't always play multiple games in the same week), # with the dates stored as ordinals (whole numbers - a feature of the timedate module), similar to this: # valid_dates = [[734228, 734229],[734235, 734236],[734241. 734242]] etc. pass @staticmethod def generate_round_robin_matchups(teams=None, play_each_team=1): ''' Note: Bulk of this code taken from: https://gist.github.com/Makistos/7192777 Parameters: :teams: (list) league team IDs. :play_each_team: (int) how many times all teams play each other. Returns: A list of all valid matchups. ''' matchups = [] if len(teams) % 2 == 1: #teams = teams + ['BYE'] teams.append(False) for i in range((len(teams) - 1) * play_each_team): mid = round(len(teams) / 2) l1 = teams[:mid] l2 = teams[mid:] l2.reverse() # Switch sides after each round if(i % 2 == 1): matchups = matchups + [ zip(l1, l2) ] else: matchups = matchups + [ zip(l2, l1) ] teams.insert(1, teams.pop()) return matchups
__________________
Politics, n. Strife of interests masquerading as a contest of principles.
--Ambrose Bierce

Last edited by Groundhog : 12-16-2016 at 07:26 PM.
Groundhog is offline   Reply With Quote