def choose_next_task(parent): """ Choose the next task to work on from among the given task's children. Upon completion, we return the Task object to work on next, or None if there are no active task objects. """ # Build a list of the active tasks which have the given parent. query = Task.objects.filter(parent=parent, status=Task.STATUS_ACTIVE) tasks = [] for task in query.order_by("ordinal_rank"): tasks.append({'task' : task}) if len(tasks) == 0: # There are no tasks we can work on -> give up. return None # Calculate the latest activity for each task. for task in tasks: task['latest_activity'] = \ activities.latest_activity_for_task(task['task']) # If a task has never been worked on, work on it now. for task in tasks: if task['latest_activity'] == None: return task # If we get here, we've worked on every task at some stage. In this case, # we find the most-recently worked-on task, and choose the one immediately # after it. latest_index = None latest_time = None for i,task in enumerate(tasks): if (latest_time == None) or (task['latest_activity'] > latest_time): latest_index = i latest_time = task['latest_activity'] if latest_index == len(tasks)-1: return tasks[0]['task'] else: return tasks[latest_index+1]['task']
def choose_next_task(parent): """ Choose the next task to work on from among the given task's children. Upon completion, we return the Task object to work on next, or None if there are no active task objects. """ # Build a list of the active tasks which have the given parent. tasks = [] for task in Task.objects.filter(parent=parent, status=Task.STATUS_ACTIVE): tasks.append({'task' : task}) # Calculate the latest activity for each task. for task in tasks: task['latest_activity'] = \ activities.latest_activity_for_task(task['task']) # If any of these tasks has never been worked on, choose the first one. for task in tasks: if task['latest_activity'] == None: return task['task'] # If we get here, every task has been worked on at least once. Choose the # date of the oldest task as our starting point. start_time = None for task in tasks: if start_time == None or start_time > task['latest_activity']: start_time = task['latest_activity'] end_time = utils.current_datetime() # If the selected start time is less than one hour ago, extend it out to # the last hour to give a more representative sample. if end_time - start_time < datetime.timedelta(hours=1): start_time = end_time - datetime.timedelta(hours=1) # Calculate the amount of time spent on each of these activities since # the oldest task. for task in tasks: task['time_spent'] = activities.time_spent_on_task(task['task'], start_time, end_time) # Calculate the total amount of time spent on all tasks thus far. tot_time_spent = 0 for task in tasks: tot_time_spent = tot_time_spent + task['time_spent'] # Calculate the relative amount of time spent on each task, and store this # as a number in the range 0..1. for task in tasks: task['relative_time_spent'] = \ float(task['time_spent']) / float(tot_time_spent) # Given the desired weightings of each task, calculate the desired relative # time spent. tot_weighting = 0.00 for task in tasks: tot_weighting = tot_weighting + task['task'].weighting if tot_weighting == 0: # We can't decide -> return the first task (if any). if len(tasks) > 0: return tasks[0]['task'] else: return None for task in tasks: task['desired_relative_time_spent'] = \ task['task'].weighting / tot_weighting # Calculate the discrepency between the desired time spent and the actual # time spent. for task in tasks: task['discrepency'] = task['desired_relative_time_spent'] \ - task['relative_time_spent'] # Finally, choose the task with the biggest (positive) discrepency. biggest_task = None biggest_discrepency = 0.00 for task in tasks: discrepency = task['discrepency'] if biggest_task == None or discrepency > biggest_discrepency: biggest_discrepency = discrepency biggest_task = task['task'] # Testing: print print "Choosing a task:" print for task in tasks: print " " + task['task'].label + ":" print " time_spent = ", task['time_spent'] print " relative_time_spent = ", task['relative_time_spent'] print " desired_relative_time_spent = ", \ task['desired_relative_time_spent'] print " discrepency = ", task['discrepency'] print # Return the task back to the caller. return biggest_task