def get_rating_fn(courses, uc): if uc.course_id not in courses: obj = {} for field in COURSE_RATING_FIELDS: obj[field] = m.AggregateRating() courses[uc.course_id] = obj return courses[uc.course_id]
def test_add_remove_ratings(self): # This sequence of add/remove ratings reproduces a long-standing bug we # used to have: sometimes when users saved ratings for a professor, the # rating would be negative (and the save wouldn't validate due to model # constraints): https://github.com/UWFlow/rmc/issues/116 # Professor Meredith is a cute kitten. Let's see if she's passionate. passion = m.AggregateRating() self.assertRating(passion, expected_rating=0.0, expected_count=0) # She's adopted by a girl named Taylor. They become happy roommates. passion.add_rating(1) self.assertRating(passion, expected_rating=1.0, expected_count=1) # But Meredith exhibits bad posture. Taylor isn't excited about that, # so she retracts her old rating for now. passion.remove_rating(1) self.assertRating(passion, expected_rating=0.0, expected_count=0) # Meredith learns how to moves her ears on command and Taylor is happy. passion.add_rating(1) self.assertRating(passion, expected_rating=1.0, expected_count=1) # But Ed is dejected after Meredith gives him a look of disapproval. passion.add_rating(0) self.assertRating(passion, expected_rating=0.5, expected_count=2) # Meredith meowed on about how Taylor can't sing, which Taylor thought # was Mean, so she changed her old approval to a disapproval. passion.remove_rating(1) passion.add_rating(0) self.assertRating(passion, expected_rating=0.0, expected_count=2)
def interest_from_scores(scores): # Course directed ratings # INTEREST # TODO(Sandy): Revise the use of this question-metric # how many classes attended i_count = scores[17]['num_replies'] i_rating = normalize_score(scores[17]) / max(1, i_count) return m.AggregateRating(rating=i_rating, count=i_count)
def overall_course_from_interest_easiness(i, e): INTEREST_WEIGHT = 0.5 EASINESS_WEIGHT = 0.5 # OVERALL oc_count = int( round(i.count * INTEREST_WEIGHT + e.count * EASINESS_WEIGHT)) oc_rating = (i.rating * INTEREST_WEIGHT + e.rating * EASINESS_WEIGHT) / max(1, oc_count) return m.AggregateRating(rating=oc_rating, count=oc_count)
def easiness_from_scores(scores): Q11_WEIGHT = 0.5 Q12_WEIGHT = 0.5 # EASINESS # difficulty of concepts e1 = normalize_score(scores[11]) * Q11_WEIGHT e1r = scores[11]['num_replies'] * Q11_WEIGHT # workload e2 = normalize_score(scores[12]) * Q12_WEIGHT e2r = scores[12]['num_replies'] * Q12_WEIGHT e_count = int(round(e1r + e2r)) e_rating = (e1 + e2) / max(1, e_count) return m.AggregateRating(rating=e_rating, count=e_count)
def get_rating_fn(courses, uc): if uc.professor_id is None: return None if uc.course_id not in courses: courses[uc.course_id] = {} professors = courses[uc.course_id] if uc.professor_id not in professors: obj = {} for field in PROFESSOR_RATING_FIELDS: obj[field] = m.AggregateRating() professors[uc.professor_id] = obj return professors[uc.professor_id]
def get_aggregate_fields_fn(uc): easiness = uc.easiness interest = uc.interest # TODO(mack): add usefulness metric def calculate_overall_rating(e, i): return ((e.count * e.rating + i.count * i.rating) / max(1, (e.count + i.count))) # heuristic for getting the overall rating: # 1. the count will max of the count for each attribute # 2. the rating will be average overall = m.AggregateRating( count=max(easiness.count, interest.count), rating=calculate_overall_rating(easiness, interest), ) return [ ('easiness', easiness), ('interest', interest), ('overall', overall), ]
def clarity_from_scores(scores): Q1_WEIGHT = 0.2 Q2_WEIGHT = 0.2 Q3_WEIGHT = 0.4 Q4_WEIGHT = 0.2 # CLARITY # presentation in lectures (organization and clarity) c1 = normalize_score(scores[1]) * Q1_WEIGHT c1r = scores[1]['num_replies'] * Q1_WEIGHT # response to questions c2 = normalize_score(scores[2]) * Q2_WEIGHT c2r = scores[2]['num_replies'] * Q2_WEIGHT # oral presentation (audibility, articulation, english) c3 = normalize_score(scores[3]) * Q3_WEIGHT c3r = scores[3]['num_replies'] * Q3_WEIGHT # visual presentation # (organization, legibility, effective use of materials) c4 = normalize_score(scores[4]) * Q4_WEIGHT c4r = scores[4]['num_replies'] * Q4_WEIGHT c_count = int(round(c1r + c2r + c3r + c4r)) c_rating = (c1 + c2 + c3 + c4) / max(1, c_count) return m.AggregateRating(rating=c_rating, count=c_count)
def overall_prof_from_scores(scores): # OVERALL # overall appraisal of quality of teaching op_count = scores[10]['num_replies'] op_rating = normalize_score(scores[10]) / max(1, op_count) return m.AggregateRating(rating=op_rating, count=op_count)
def passion_from_scores(scores): # PASSION # attitude towards teachings the course p_count = scores[8]['num_replies'] p_rating = normalize_score(scores[8]) / max(1, p_count) return m.AggregateRating(rating=p_rating, count=p_count)