# transcript.py # YOUR NAME HERE # skeleton by Lillian Lee (LJL2) and Steve Marschner (SRM2), Feb 9 2014 # DATE YOU COMPLETED THIS HERE """Module providing a class and constants for representing transcripts. """ # List of valid "base" letter names. # At this university, everybody is above average! LETTER_LIST = ['B', 'A'] # List of valid modifiers to base letter grades. MODIFIER_LIST = ['-','+'] def lettergrade_to_val(lg): """Returns: numerical value of letter grade lg. The usual numerical scheme is assumed: A+ -> 4.3, A -> 4.0, A- -> 3.7, etc. Precondition: lg is a 1 or 2-character string consisting of a "base" letter in LETTER_LIST optionally followed by a modifier in MODIFIER_LIST.""" # if LETTER_LIST or MODIFIER_LIST change, the implementation of # this function must change. # get value of base letter. Trick: index in LETTER_LIST is shifted from value bv = LETTER_LIST.index(lg[0]) + 3 # Trick with indexing in MODIFIER_LIST to get the modifier value return bv + ((MODIFIER_LIST.index(lg[1]) - .5)*.3/.5 if (len(lg) == 2) else 0) class Titem(object): """A Titem is an 'item' on a transcript, like "CS1110 A+" Instance variables: course [string]: course name. Always at least 1 character long. gradeval [float]: the numerical equivalent of the letter grade. Valid letter grades are 1 or 2 chars long, and consist of a "base" letter in LETTER_LIST optionally followed by a modifier in MODIFIER_LIST. We store values instead of letter grades to facilitate calculations of GPA later. (In "real" life, one would write a function that, when displaying a Titem, would display the letter grade even though the underlying representation is numerical, but we're keeping things simple for this lab.) """ def __init__(self, n, lg): """Initializer: A new transcript line with course (name) n, gradeval the numerical equivalent of letter grade lg. Preconditions: n is a non-empty string. lg is a string consisting of a "base" letter in LETTER_LIST optionally followed by modifier in MODIFIER_LIST. """ # assert statements that cause an error when preconditions are violated assert type(n) == str and type(lg) == str, 'argument type error' assert (len(n) >= 1 and 0 < len(lg) <= 2 and lg[0] in LETTER_LIST and (len(lg) == 1 or lg[1] in MODIFIER_LIST)), 'argument value error' self.course = n self.gradeval = lettergrade_to_val(lg) def raise_grade(ti): """"Raise gradeval of transcript line ti by a non-noticeable amount. We imagine that this function is written by some mischievous entity with access to the university registrar's records. The idea is that raising a grade of B- to a B, or B to a B+, could escape notice. But, someone might notice a change of B+ to A, since that's very "visible". So, ti's gradeval is raised by .3 unless the gradeval already corresponds to a "plus" grade like B+, in which case the gradeval is not changed. Preconditions: ti is a Titem. """ # value of the base letter grade, e.g., 4 (or 4.0) for a 4.3 bval = int(ti.gradeval) # part after decimal point in raised grade, e.g., 3 (or 3.0) for a 4.3 newdec = min(int((ti.gradeval + .3)*10) % 10, 3) # get result by add the two values together, after shifting newdec one # decimal place newval = bval + round(newdec/10.0, 1) ti.gradeval = newval