This is my code for a simple GPA calculator. I am getting an error (see report) even though there is one course in the list as I follow the input and enter in the course. Maybe it has something to do with the placement of the call to the displayOutputTable function?
class Course(object):
def __init__(self, courseName, letterGrade):
self.courseName = courseName
self.letterGrade = letterGrade
courseList = []
def acceptInput():
courseList = []
choice = input("Type ‘a’ to add new class or ‘e’ to end. ")
if choice == 'a':
courseName = input("Class Name? ")
letterGrade = input("Grade? ")
course = Course(courseName, letterGrade)
courseList = courseList + [course]
print(courseList)
# Create Course object using local data from user
# Add this new course object to courseList list
def convertGradeToPoints(letterGrade):
creditValue = 0
for i in courseList:
if letterGrade == "A":
creditValue = 4.0
if letterGrade == "B":
creditValue = 3.0
if letterGrade == "C":
creditValue = 2.0
if letterGrade == "D":
creditValue = 1.0
if letterGrade == "F":
creditValue = 0.0
return creditValue
def calculateGPA():
numbercourseList = len(courseList)
totalpoints = 0
for course in courseList:
totalpoints = totalpoints + convertGradeToPoints(course.letterGrade)
return totalpoints/numbercourseList
def displayOutputTable():
print ("COURSE NAME \t LETTER GRADE \t POINTS")
print("-------------------------")
for course in courseList:
print(course.courseName + "\t" + course.letterGrade + "\t" + convertGradeToPoints(course.letterGrade))
print("Total unweighted gpa" + "\t" + str(calculateGPA()))
acceptInput()
displayOutputTable()
here is the error report:
Traceback (most recent call last):
File "C:/Users/Fred/Desktop/tester.py", line 56, in <module>
displayOutputTable()
File "C:/Users/Fred/Desktop/tester.py", line 53, in displayOutputTable
print("Total unweighted gpa" + "\t" + str(calculateGPA()))
File "C:/Users/Fred/Desktop/tester.py", line 44, in calculateGPA
return totalpoints/numbercourseList
ZeroDivisionError: int division or modulo by zero
course[] is a global variable. You can only reassign a global variable in a local scope by first declaring it global to bind the global name to the local scope. Otherwise, when you do courseList = [], what's actually happening is a new variable named courseList is assigned a list in the local scope.
def acceptInput():
global courseList
courseList = []
choice = input("Type ‘a’ to add new class or ‘e’ to end. ")
if choice == 'a':
courseName = input("Class Name? ")
letterGrade = input("Grade? ")
course = Course(courseName, letterGrade)
courseList = courseList + [course]
print(courseList)
# Create Course object using local data from user
# Add this new course object to courseList list
Alternatively, the way to do it by only mutating the LIST object without REASSIGNING it.
def acceptInput():
courseList.clear()
choice = input("Type ‘a’ to add new class or ‘e’ to end. ")
if choice == 'a':
courseName = input("Class Name? ")
letterGrade = input("Grade? ")
course = Course(courseName, letterGrade)
courseList.append(course)
print(courseList)
# Create Course object using local data from user
# Add this new course object to courseList list
Also, not sure why you want to clear your list of courses every time you accept input of a new course. You'll only ever have one course this way.
Edited for your comment:
How do I make it so the console keeps asking me for input after I submit one class
The answer to this is to use a looping construct, which is a fundamental basic construct of every imperative programming language out there. Perhaps you'd do well to consider learning from a basic python tutorial such as LearnPythonTheHardWay if you do not know this.
I'll also include a sigterm/sigint handler to handle ctrl+c without exception.
import signal
stop = False
def exit():
global stop
stop = True
signal.signal(signal.SIGINT, lambda signum, frame: exit())
signal.signal(signal.SIGTERM, lambda signum, frame: exit())
while not stop:
acceptInput()
displayOutputTable()