In [ ]:
class Student():

    #constructor method
    def __init__(self,n,m):
        self.name = n
        self.major = m
        self.courses = []
    
    # getter
    def get_name(self):
        return self.name

    #setter
    def set_name(self,n):
        self.name = n
    
    # method to add a course to a student object
    def add_course(self,cno,credits,grade):
        self.courses.append((cno,credits,grade))

    def change_grade(self,cno,credits,newgrade):
        pass # write this method as practice

    def generate_transcript(self):
        # return string 
        pass # write this method as practice

    def gpa(self):
        ncredits = 0
        points = 0.0
        grade_points = {'A':4, 'B':3, 'C':2, 'D':1, 'F':0}
        for (cno,credits,grade) in self.courses:
            ncredits = ncredits + credits
            points = points + (credits * grade_points[grade])
        if ncredits > 0:
            return points/ncredits
        else:
            return None
 
    #to_string method
    def __str__(self):
        return self.name + ":" + \
               self.major + ":" + \
               str(len(self.courses)) + \
               " courses"
    
In [ ]:
s1 = Student("John","CSC")
s2 = Student("Alice","Math")

s1.add_course("1301",4,'A')
s1.add_course("1302",4,'A')
s1.add_course("2510",3,'A')

s2.add_course("1301",4,'B')
s2.add_course("1301",4,'C')

s3 = Student("Newbee","CSC")

print(s1, s1.gpa())
print(s2, s2.gpa())
print(s3, s3.gpa())
John:CSC:3 courses 4.0
Alice:Math:2 courses 2.5
Newbee:CSC:0 courses None