forked from orn688/swarthmore-gpa-calculator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.py
74 lines (66 loc) · 2.63 KB
/
helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from sympy.functions import re
import re
# Official grade point equivalencies from the Swarthmore College registrar
GRADE_POINT_EQUIVS = {'A+': 4.0,
'A' : 4.0,
'A-': 3.67,
'B+': 3.33,
'B' : 3.0,
'B-': 2.67,
'C+': 2.33,
'C' : 2.0,
'C-': 1.67,
'D+': 1.33,
'D' : 1.0,
'D-': 0.67,
'F' : 0.0,
}
def grade_point_equiv(grade_str):
if grade_str in GRADE_POINT_EQUIVS:
# Grade is already in letter format
return GRADE_POINT_EQUIVS[grade_str]
elif re.match(r'[0-4].[0-9]{1,2}$', grade_str):
# Grade is formatted as a grade point float (for Bryn Mawr and
# Haverford classes)
return float(grade_str)
else:
# Course grade is not in valid format (e.g., 1, CR, NC) and
# doesn't affect GPA
return None
def parse_grades(raw_grades):
"""Convert from a string of grades to a structured dict.
Args:
raw_grades: A string containing the user's raw grades copied and pasted
from MySwarthmore (hopefully)
Returns:
A list of dicts, one per course found while parsing raw_grades, with
the fields: ['affects_gpa', 'course', 'title', 'credits_earned', 'grade',
'division', 'instructor']
"""
lines = raw_grades.split("\n")
# Remove term header lines
course_exp = re.compile("[A-Z]{4}\s\d{3}") # Course regex
def is_course_line(line):
return line.strip() and \
course_exp.search(line)
courses = list(filter(is_course_line, lines))
# Convert each course row to a dict
course_list = []
for course in courses:
course_info = [field.strip() for field in course.split("\t")] # Split up fields of row
course_info = course_info[1:] # Chop off the tab or the term
course_info.append(True) # Assume course affects GPA
course_fields = ['course',
'title',
'credits_attemped',
'credits_earned',
'grade',
'division',
'instructor',
'affects_gpa']
if len(course_info) == len(course_fields):
course_dict = dict(zip(course_fields, course_info))
if grade_point_equiv(course_dict['grade']) is None:
course_dict['affects_gpa'] = False
course_list.append(course_dict)
return course_list