def compute(self, courses, progress_overrides, progress_assertions):
    'Computes and stores the status of the requirements statement using the\n        given list of Course objects.'
    satisfied_courses = set()
    if self.compute_assertions(courses, progress_assertions):
        self.bypass_children()
        return
    if (self.list_path in progress_overrides):
        manual_progress = progress_overrides[self.list_path]
    else:
        manual_progress = 0
    self.is_bypassed = False
    self.assertion = None
    if (self.statement.requirement is not None):
        if (self.statement.is_plain_string and (manual_progress != 0) and (self.threshold is not None)):
            self.override_requirement(manual_progress)
            return
        else:
            (whole_courses, half_courses) = self.courses_satisfying_req(courses)
            satisfied_courses = (whole_courses + half_courses)
            if (not (self.threshold is None)):
                subject_progress = ceiling_thresh((len(whole_courses) + (len(half_courses) // 2)), self.threshold.cutoff_for_criterion(CRITERION_SUBJECTS))
                unit_progress = ceiling_thresh(total_units(satisfied_courses), self.threshold.cutoff_for_criterion(CRITERION_UNITS))
                is_fulfilled = self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress)
            else:
                progress_subjects = min(len(satisfied_courses), 1)
                is_fulfilled = (len(satisfied_courses) > 0)
                subject_progress = ceiling_thresh(progress_subjects, 1)
                if (len(satisfied_courses) > 0):
                    unit_progress = ceiling_thresh(list(satisfied_courses)[0].total_units, DEFAULT_UNIT_COUNT)
                else:
                    unit_progress = ceiling_thresh(0, DEFAULT_UNIT_COUNT)
        progress = (unit_progress if ((self.threshold is not None) and (self.threshold.criterion == CRITERION_UNITS)) else subject_progress)
    if (len(self.children) > 0):
        num_reqs_satisfied = 0
        satisfied_by_category = []
        satisfied_courses = set()
        num_courses_satisfied = 0
        open_children = []
        for req_progress in self.children:
            req_progress.compute(courses, progress_overrides, progress_assertions)
            req_satisfied_courses = req_progress.satisfied_courses
            if (req_progress.assertion and req_progress.assertion.get('ignore', False)):
                continue
            open_children.append(req_progress)
            if (req_progress.is_fulfilled and (len(req_progress.satisfied_courses) > 0)):
                num_reqs_satisfied += 1
            satisfied_courses.update(req_satisfied_courses)
            satisfied_by_category.append(list(req_satisfied_courses))
            if ((req_progress.statement.connection_type == CONNECTION_TYPE_ALL) and req_progress.children):
                num_courses_satisfied += (req_progress.is_fulfilled and (len(req_progress.satisfied_courses) > 0))
            else:
                num_courses_satisfied += len(req_satisfied_courses)
        satisfied_by_category = [sat for (prog, sat) in sorted(zip(open_children, satisfied_by_category), key=(lambda z: z[0].raw_fraction_fulfilled), reverse=True)]
        sorted_progresses = sorted(open_children, key=(lambda req: req.raw_fraction_fulfilled), reverse=True)
        if ((self.threshold is None) and (self.distinct_threshold is None)):
            is_fulfilled = (num_reqs_satisfied > 0)
            if (self.statement.connection_type == CONNECTION_TYPE_ANY):
                if (len(sorted_progresses) > 0):
                    subject_progress = sorted_progresses[0].subject_fulfillment
                    unit_progress = sorted_progresses[0].unit_fulfillment
                else:
                    subject_progress = Progress(0, 0)
                    unit_progress = Progress(0, 0)
            else:
                subject_progress = sum_progresses(sorted_progresses, CRITERION_SUBJECTS, None)
                unit_progress = sum_progresses(sorted_progresses, CRITERION_UNITS, None)
        else:
            if (self.distinct_threshold is not None):
                num_progresses_to_count = min(self.distinct_threshold.get_actual_cutoff(), len(sorted_progresses))
                sorted_progresses = sorted_progresses[:num_progresses_to_count]
                satisfied_by_category = satisfied_by_category[:num_progresses_to_count]
                satisfied_courses = set()
                num_courses_satisfied = 0
                for (i, child) in zip(range(num_progresses_to_count), open_children):
                    satisfied_courses.update(satisfied_by_category[i])
                    if (child.statement.connection_type == CONNECTION_TYPE_ALL):
                        num_courses_satisfied += (child.is_fulfilled and (len(child.satisfied_courses) > 0))
                    else:
                        num_courses_satisfied += len(satisfied_by_category[i])
            if ((self.threshold is None) and (self.distinct_threshold is not None)):
                if ((self.distinct_threshold == THRESHOLD_TYPE_GTE) or (self.distinct_threshold.type == THRESHOLD_TYPE_GT)):
                    is_fulfilled = (num_reqs_satisfied >= self.distinct_threshold.get_actual_cutoff())
                else:
                    is_fulfilled = True
                subject_progress = sum_progresses(sorted_progresses, CRITERION_SUBJECTS, (lambda x: max(x, 1)))
                unit_progress = sum_progresses(sorted_progresses, CRITERION_UNITS, (lambda x: (x, DEFAULT_UNIT_COUNT)[(x == 0)]))
            elif (self.threshold is not None):
                subject_progress = Progress(num_courses_satisfied, self.threshold.cutoff_for_criterion(CRITERION_SUBJECTS))
                unit_progress = Progress(total_units(satisfied_courses), self.threshold.cutoff_for_criterion(CRITERION_UNITS))
                if ((self.distinct_threshold is not None) and ((self.distinct_threshold.type == THRESHOLD_TYPE_GT) or (self.distinct_threshold.type == THRESHOLD_TYPE_GTE))):
                    is_fulfilled = (self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress) and (num_reqs_satisfied >= self.distinct_threshold.get_actual_cutoff()))
                    if (num_reqs_satisfied < self.distinct_threshold.get_actual_cutoff()):
                        (subject_progress, unit_progress) = force_unfill_progresses(satisfied_by_category, self.distinct_threshold, self.threshold)
                else:
                    is_fulfilled = self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress)
        if (self.statement.connection_type == CONNECTION_TYPE_ALL):
            is_fulfilled = (is_fulfilled and (num_reqs_satisfied == len(open_children)))
            if ((subject_progress.progress == subject_progress.max) and (len(open_children) > num_reqs_satisfied)):
                subject_progress.max += (len(open_children) - num_reqs_satisfied)
                unit_progress.max += ((len(open_children) - num_reqs_satisfied) * DEFAULT_UNIT_COUNT)
        subject_progress = ceiling_thresh(subject_progress.progress, subject_progress.max)
        unit_progress = ceiling_thresh(unit_progress.progress, unit_progress.max)
        progress = (unit_progress if ((self.threshold is not None) and (self.threshold.criterion == CRITERION_UNITS)) else subject_progress)
    progress_units = (CRITERION_SUBJECTS if (self.threshold is None) else self.threshold.criterion)
    self.is_fulfilled = is_fulfilled
    self.subject_fulfillment = subject_progress
    self.subject_progress = subject_progress.progress
    self.subject_max = subject_progress.max
    self.unit_fulfillment = unit_progress
    self.unit_progress = unit_progress.progress
    self.unit_max = unit_progress.max
    self.progress = progress.progress
    self.progress_max = progress.max
    self.percent_fulfilled = progress.get_percent()
    self.fraction_fulfilled = progress.get_fraction()
    self.raw_fraction_fulfilled = progress.get_raw_fraction(progress_units)
    self.satisfied_courses = list(satisfied_courses)
Computes and stores the status of the requirements statement using the
given list of Course objects.
def compute(self, courses, progress_overrides, progress_assertions):
    'Computes and stores the status of the requirements statement using the\n        given list of Course objects.'
    satisfied_courses = set()
    if self.compute_assertions(courses, progress_assertions):
        self.bypass_children()
        return
    if (self.list_path in progress_overrides):
        manual_progress = progress_overrides[self.list_path]
    else:
        manual_progress = 0
    self.is_bypassed = False
    self.assertion = None
    if (self.statement.requirement is not None):
        if (self.statement.is_plain_string and (manual_progress != 0) and (self.threshold is not None)):
            self.override_requirement(manual_progress)
            return
        else:
            (whole_courses, half_courses) = self.courses_satisfying_req(courses)
            satisfied_courses = (whole_courses + half_courses)
            if (not (self.threshold is None)):
                subject_progress = ceiling_thresh((len(whole_courses) + (len(half_courses) // 2)), self.threshold.cutoff_for_criterion(CRITERION_SUBJECTS))
                unit_progress = ceiling_thresh(total_units(satisfied_courses), self.threshold.cutoff_for_criterion(CRITERION_UNITS))
                is_fulfilled = self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress)
            else:
                progress_subjects = min(len(satisfied_courses), 1)
                is_fulfilled = (len(satisfied_courses) > 0)
                subject_progress = ceiling_thresh(progress_subjects, 1)
                if (len(satisfied_courses) > 0):
                    unit_progress = ceiling_thresh(list(satisfied_courses)[0].total_units, DEFAULT_UNIT_COUNT)
                else:
                    unit_progress = ceiling_thresh(0, DEFAULT_UNIT_COUNT)
        progress = (unit_progress if ((self.threshold is not None) and (self.threshold.criterion == CRITERION_UNITS)) else subject_progress)
    if (len(self.children) > 0):
        num_reqs_satisfied = 0
        satisfied_by_category = []
        satisfied_courses = set()
        num_courses_satisfied = 0
        open_children = []
        for req_progress in self.children:
            req_progress.compute(courses, progress_overrides, progress_assertions)
            req_satisfied_courses = req_progress.satisfied_courses
            if (req_progress.assertion and req_progress.assertion.get('ignore', False)):
                continue
            open_children.append(req_progress)
            if (req_progress.is_fulfilled and (len(req_progress.satisfied_courses) > 0)):
                num_reqs_satisfied += 1
            satisfied_courses.update(req_satisfied_courses)
            satisfied_by_category.append(list(req_satisfied_courses))
            if ((req_progress.statement.connection_type == CONNECTION_TYPE_ALL) and req_progress.children):
                num_courses_satisfied += (req_progress.is_fulfilled and (len(req_progress.satisfied_courses) > 0))
            else:
                num_courses_satisfied += len(req_satisfied_courses)
        satisfied_by_category = [sat for (prog, sat) in sorted(zip(open_children, satisfied_by_category), key=(lambda z: z[0].raw_fraction_fulfilled), reverse=True)]
        sorted_progresses = sorted(open_children, key=(lambda req: req.raw_fraction_fulfilled), reverse=True)
        if ((self.threshold is None) and (self.distinct_threshold is None)):
            is_fulfilled = (num_reqs_satisfied > 0)
            if (self.statement.connection_type == CONNECTION_TYPE_ANY):
                if (len(sorted_progresses) > 0):
                    subject_progress = sorted_progresses[0].subject_fulfillment
                    unit_progress = sorted_progresses[0].unit_fulfillment
                else:
                    subject_progress = Progress(0, 0)
                    unit_progress = Progress(0, 0)
            else:
                subject_progress = sum_progresses(sorted_progresses, CRITERION_SUBJECTS, None)
                unit_progress = sum_progresses(sorted_progresses, CRITERION_UNITS, None)
        else:
            if (self.distinct_threshold is not None):
                num_progresses_to_count = min(self.distinct_threshold.get_actual_cutoff(), len(sorted_progresses))
                sorted_progresses = sorted_progresses[:num_progresses_to_count]
                satisfied_by_category = satisfied_by_category[:num_progresses_to_count]
                satisfied_courses = set()
                num_courses_satisfied = 0
                for (i, child) in zip(range(num_progresses_to_count), open_children):
                    satisfied_courses.update(satisfied_by_category[i])
                    if (child.statement.connection_type == CONNECTION_TYPE_ALL):
                        num_courses_satisfied += (child.is_fulfilled and (len(child.satisfied_courses) > 0))
                    else:
                        num_courses_satisfied += len(satisfied_by_category[i])
            if ((self.threshold is None) and (self.distinct_threshold is not None)):
                if ((self.distinct_threshold == THRESHOLD_TYPE_GTE) or (self.distinct_threshold.type == THRESHOLD_TYPE_GT)):
                    is_fulfilled = (num_reqs_satisfied >= self.distinct_threshold.get_actual_cutoff())
                else:
                    is_fulfilled = True
                subject_progress = sum_progresses(sorted_progresses, CRITERION_SUBJECTS, (lambda x: max(x, 1)))
                unit_progress = sum_progresses(sorted_progresses, CRITERION_UNITS, (lambda x: (x, DEFAULT_UNIT_COUNT)[(x == 0)]))
            elif (self.threshold is not None):
                subject_progress = Progress(num_courses_satisfied, self.threshold.cutoff_for_criterion(CRITERION_SUBJECTS))
                unit_progress = Progress(total_units(satisfied_courses), self.threshold.cutoff_for_criterion(CRITERION_UNITS))
                if ((self.distinct_threshold is not None) and ((self.distinct_threshold.type == THRESHOLD_TYPE_GT) or (self.distinct_threshold.type == THRESHOLD_TYPE_GTE))):
                    is_fulfilled = (self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress) and (num_reqs_satisfied >= self.distinct_threshold.get_actual_cutoff()))
                    if (num_reqs_satisfied < self.distinct_threshold.get_actual_cutoff()):
                        (subject_progress, unit_progress) = force_unfill_progresses(satisfied_by_category, self.distinct_threshold, self.threshold)
                else:
                    is_fulfilled = self.threshold.is_satisfied_by(subject_progress.progress, unit_progress.progress)
        if (self.statement.connection_type == CONNECTION_TYPE_ALL):
            is_fulfilled = (is_fulfilled and (num_reqs_satisfied == len(open_children)))
            if ((subject_progress.progress == subject_progress.max) and (len(open_children) > num_reqs_satisfied)):
                subject_progress.max += (len(open_children) - num_reqs_satisfied)
                unit_progress.max += ((len(open_children) - num_reqs_satisfied) * DEFAULT_UNIT_COUNT)
        subject_progress = ceiling_thresh(subject_progress.progress, subject_progress.max)
        unit_progress = ceiling_thresh(unit_progress.progress, unit_progress.max)
        progress = (unit_progress if ((self.threshold is not None) and (self.threshold.criterion == CRITERION_UNITS)) else subject_progress)
    progress_units = (CRITERION_SUBJECTS if (self.threshold is None) else self.threshold.criterion)
    self.is_fulfilled = is_fulfilled
    self.subject_fulfillment = subject_progress
    self.subject_progress = subject_progress.progress
    self.subject_max = subject_progress.max
    self.unit_fulfillment = unit_progress
    self.unit_progress = unit_progress.progress
    self.unit_max = unit_progress.max
    self.progress = progress.progress
    self.progress_max = progress.max
    self.percent_fulfilled = progress.get_percent()
    self.fraction_fulfilled = progress.get_fraction()
    self.raw_fraction_fulfilled = progress.get_raw_fraction(progress_units)
    self.satisfied_courses = list(satisfied_courses)