def extensibilityFilter(self, all_events, extensibility):
        '''right now can only increase he length of free events'''
        '''needs more work'''
        remove_list = list()

        for i in range(len(all_events)):
            event = all_events[i]
            custom_tags = calhelp.getCustomTags(event)
            shortenability = custom_tags['shortenability']
            reschedulability = custom_tags['reschedulability']

            if shortenability != 0:

                if reschedulability <= -1:
                    if i == 0:
                        next_custom_tags = calhelp.getCustomTags(all_events[i +
                                                                            1])
                        all_events[i]['extendable_by'] = next_custom_tags[
                            'shortenability']

                    elif i == len(all_events) - 1:
                        prev_custom_tags = calhelp.getCustomTags(all_events[i -
                                                                            1])
                        all_events[i]['extendable_by'] = prev_custom_tags[
                            'shortenability']
                    else:
                        next_custom_tags = calhelp.getCustomTags(all_events[i +
                                                                            1])
                        prev_custom_tags = calhelp.getCustomTags(all_events[i -
                                                                            1])
                        all_events[i]['extendable_by'] = next_custom_tags[
                            'shortenability'] + prev_custom_tags[
                                'shortenability']

        return all_events
    def IUScaleRanker(self, events, target_event):
        target_custom_tags = calhelp.getCustomTags(target_event)
        importance = target_custom_tags['importance']
        urgency = target_custom_tags['urgency']

        for event in events:
            event_custom_tags = calhelp.getCustomTags(event)
            event_importance = event_custom_tags['importance']
            event_urgency = event_custom_tags['urgency']

            event_IUScore = int(importance) + int(urgency) - (
                int(event_importance) + int(event_urgency))

            event['IUScore'] = event_IUScore

        return events
    def timeLagRanker(self, events, target_event, weight=1):
        '''This ranks events slots by calculating how far back the event has 
        been pushed into future. Ideally, we want the event to take place as
        early as possible'''

        target_expire_days = calhelp.calcEventExpireDays(target_event)
        custom_tags = calhelp.getCustomTags(target_event)
        urgency = int(custom_tags['urgency'])
        today = datetime.date.today()
        upper_bound = today
        lower_bound = today + datetime.timedelta(days=int(target_expire_days /
                                                          (urgency + 1)))
        scoring_period = lower_bound - upper_bound
        scoring_period = scoring_period.days

        for event in events:
            event_start_date = calhelp.str2time(
                event['start']['dateTime']).date()
            from_lower_bound = lower_bound - event_start_date
            from_lower_bound = from_lower_bound.days
            if scoring_period == 0:
                if from_lower_bound == 0:
                    time_lag_score = 1
                else:
                    time_lag_score = 0
            else:
                if from_lower_bound <= 0:
                    time_lag_score = 0
                else:
                    time_lag_score = weight * from_lower_bound / scoring_period

            event['time_lag_score'] = time_lag_score

        return events
    def reschedulabilityFilter(self, all_events, reschedulability):
        reschedulability = str(reschedulability)
        remove_list = list()
        for event in all_events:
            custom_tag = calhelp.getCustomTags(event)
            if not custom_tag['reschedulability'] == reschedulability:
                remove_list.append(event)
        for event in remove_list:
            all_events.remove(event)

        return all_events
 def scheduleBucketList(self):
     if self.bucket_list:
         for event in self.bucket_list:
             print('Scheduling event:' + event['summary'] + '.....')
             start_datetime = calhelp.str2time(event['start']['dateTime'])
             custom_tags = calhelp.getCustomTags(event)
             days_till_expire = custom_tags['days_till_expire']
             success = self.rescheduler(event, start_datetime,
                                        days_till_expire)
             if success:
                 print(event['summary'] +
                       ' has been scheduled successfully!')
                 print()
             else:
                 print(event['summary'] + ' cannot be scheduled')
     else:
         print('bucket list is empty !')
    def stressRanker(self, events):
        '''this is intended to rank events based on how stressful it would be to schedule the event'''
        '''right now the design idea is to loop through each day and count event types then assign socres'''
        '''pending tests to be written and run: 1.with a event period less than 2 days. 2.with event types that 
        are not defined for stress level'''

        # variable initialization
        all_events = list()
        day_events = list()
        date_changed_once = 0
        first_loop = 1
        stress_level = 0
        try:
            stress_def = self.getEventStressDef()
        except:
            warnings.warn(
                'Cannot load Stress Definitions. Please create stress definitions.'
            )
            stress_def = {}

        for event in events:
            event_date = calhelp.str2time(event['start']['dateTime'])
            event_date = event_date.date()
            if first_loop:
                temp_date = event_date
                first_loop = 0

            if event_date != temp_date:
                date_changed = 1
                date_changed_once = 1
            else:
                date_changed = 0

            temp_date = event_date

            if date_changed:
                for event in day_events:
                    stress_score = 2 / (1 + math.exp(-1 * stress_level)) - 1
                    event['stress_score'] = stress_score

                all_events = all_events + day_events
                stress_level = 0
                day_events = list()

            day_events.append(event)
            event_tags = calhelp.getCustomTags(event)
            event_type = event_tags['event_type']
            stress_level += stress_def.get(event_type, -99)
            if stress_level == -99:
                warnings.warn('No event_type definitions for ' + event_type +
                              ' found. Value 0 will be used')
                stress_level = 0

        if not date_changed_once:

            for event in day_events:
                event['stress_score'] = stress_level

            all_events = all_events + day_events

        return all_events
    def scheduleDailyEvent(self,
                           event_template={},
                           event={},
                           period_start_date=-1,
                           period_end_date=-1,
                           by_week=False,
                           by_week_day='MO,TU,WE,TH,FR',
                           by_daily=False,
                           by_daily_interval=0,
                           default_start_time=datetime.time(0, 0)):
        #constant definition
        week_day_dict = {
            'MO': 0,
            'TU': 1,
            'WE': 2,
            'TH': 3,
            'FR': 4,
            'SA': 5,
            'SU': 6
        }
        instance_count = 0

        if not event and not event_template:
            raise ValueError('An event_template or event need to be provided')
        elif event_template:
            event = self.newEvent(event_template=event_template,
                                  start=datetime.datetime.combine(
                                      period_start_date, default_start_time),
                                  expirary_date=period_end_date)

        # -- set defualt parameter value
        if period_start_date == -1:
            period_start_date = calhelp.str2time(event['start']['dateTime'])
            period_start_date = period_start_date.date()

        if period_end_date == -1:
            custom_tags = calhelp.getCustomTags(event)
            period_end_date = calhelp.str2time(
                custom_tags['expirary_date']).date()

        if not by_week and not by_daily:
            by_week = True

        # -- verifying arguments
        if not type(period_start_date) is datetime.date:
            raise ValueError(
                'variable period_start_date not a datetime.date object')

        if not type(period_end_date) is datetime.date:
            raise ValueError(
                'variable period_end_date not a datetime.date object')

        if by_week and by_daily:
            raise ValueError(
                'Please specifiy by_week or by_daily. Only one may be true.')

        if by_week:
            if not by_week_day:
                raise ValueError('by_week_day invalid')
            else:
                key1 = 0
                week_days = list()

                while True:
                    key2 = by_week_day.find(',', key1)
                    if key2 == -1:
                        week_day = by_week_day[key1:len(by_week_day)]
                    else:
                        week_day = by_week_day[key1:key2]

                    if week_day in week_day_dict:
                        week_day = week_day_dict[week_day]
                    else:
                        raise ValueError('by_week_day invalid')
                    week_days.append(week_day)

                    if key2 == -1:
                        break
                    key1 = key2 + 1

                if not week_days:
                    raise ValueError('by_week_day invalid')

            t_days = period_end_date - period_start_date
            t_days = t_days.days
            for i in range(t_days + 1):
                day = period_start_date + datetime.timedelta(days=i)
                week_day = day.weekday()
                if week_day in week_days:
                    start_datetime = datetime.datetime.combine(
                        day, default_start_time)
                    success = self.rescheduler(event, start_datetime, 0)
                    if success:
                        instance_count += 1
                    if not success:
                        print('Unable to schedule on day ' + str(day))

        elif by_daily:

            interval = int(by_daily_interval) + 1
            t_days = period_end_date - period_start_date
            t_days = t_days.days + 1
            ndays = round((t_days - 1) / interval) + 1

            for i in range(ndays):
                day = period_start_date + datetime.timedelta(days=i * interval)
                if day > period_end_date:
                    break
                start_datetime = datetime.datetime.combine(
                    day, default_start_time)
                success = self.rescheduler(event, start_datetime, 0)
                if success:
                    instance_count += 1
                if not success:
                    print('Unable to schedule on day' + str(day))

        print()
        print('Success! ', instance_count, 'instances of event ',
              event['summary'], ' scheduled!')