# File: courseSelector.py # Purpose: Different classes to select courses in order to maximize # value without going over the limit of available effort. # # Author: TODO # # Collaboration statement: TODO from course import Course ############################################################# class CourseSelector: def __init__(self, courses = []): self.courses = courses[:] # copy the courses def addCourse(self, course): self.courses.append(course) def chooseCourses(self, maxEffort): raise NotImplementedError # will implement in a subclass ############################################################# class GreedyCourseSelector(CourseSelector): def __init__(self, courses = []): # Don't do anything special, just call the parent constructor # to initialize the courses CourseSelector.__init__(self, courses) def greedyChoice(self, course): raise NotImplementedError # will implement in subclasses def chooseCourses(self, maxEffort): """ Choose courses greedily, using a pre-determined greedy evaluation function, without going over maxEffort. returns: value, effort, and list of courses """ # Sort the courses based on the greedy evaluation function # (this must be defined in subclasses) # Choose courses as long as the total effort isn't more # than maxEffort # Return the value, effort, and the chosen courses return 0, 0, [] # TODO: replace with your code ############################################################# class ValueGreedyCourseSelector(GreedyCourseSelector): """ A greedy course selector that favors courses with high value, regardless of effort. """ def __init__(self, courses = []): # Don't do anything special, just call the parent constructor # to initialize the courses GreedyCourseSelector.__init__(self, courses) def greedyChoice(self, course): # Favor courses with high value, regardless of effort return 0 # TODO: replace with your code class EffortGreedyCourseSelector(GreedyCourseSelector): """ A greedy course selector that favors courses with low effort, regardless of value. """ def __init__(self, courses = []): # Don't do anything special, just call the parent constructor # to initialize the courses GreedyCourseSelector.__init__(self, courses) def greedyChoice(self, course): # Favor courses with low effort, regardless of value return 0 # TODO: replace with your code class ValuePerEffortGreedyCourseSelector(GreedyCourseSelector): """ A greedy course selector that favors courses with high value-to-effort ratio. """ def __init__(self, courses = []): # Don't do anything special, just call the parent constructor # to initialize the courses GreedyCourseSelector.__init__(self, courses) def greedyChoice(self, course): # Favor courses with high value-to-effort ratio return 0 # TODO: replace with your code ############################################################# def testSolutions(): courses = [Course("A", 6, 10, 4), Course("B", 6, 5, 10), Course("C", 6, 2, 4), Course("D", 6, 6, 8), Course("E", 6, 3, 3), Course("F", 6, 8, 2), Course("G", 6, 4, 7)] valueGreedyCourseSelector = ValueGreedyCourseSelector(courses) effortGreedyCourseSelector = EffortGreedyCourseSelector(courses) valuePerEffortGreedyCourseSelector = ValuePerEffortGreedyCourseSelector(courses) maxEffort = 12 print("Maximum effort:", maxEffort) print("\nValue greedy result:") res = valueGreedyCourseSelector.chooseCourses(maxEffort) print(" value:", res[0]) print(" effort:", res[1]) for course in res[2]: print(" " + str(course)) print("\nEffort greedy result:") res = effortGreedyCourseSelector.chooseCourses(maxEffort) print(" value:", res[0]) print(" effort:", res[1]) for course in res[2]: print(" " + str(course)) print("\nValue-to-effort ratio greedy result:") res = valuePerEffortGreedyCourseSelector.chooseCourses(maxEffort) print(" value:", res[0]) print(" effort:", res[1]) for course in res[2]: print(" " + str(course)) if __name__ == "__main__": testSolutions()