2
\$\begingroup\$

As part of a project I made a GPA calculator. It takes in the class name and letter grade for that class and adds them to a list (eventually I'll add some features that require me to have the grades and classes paired to each other) then adds points according to the grade and then divides by 6 the number of classes I have and gives me a total GPA.

        #GPA Calc

#Lists 
classes= []
grades = []

#Collects the data of Class names and Grades in Letter Form
def collect():
    i = 0
    while (i <= 5):
        className = input("Enter Class Name: ")
        classes.append(className)
        i = i +1


    print(classes)
    y = 0
    while (y <=5):
        grade = input("Enter Your Grade For Each Class Listed in Order (Letter Form): ")
        grade = grade.upper()
        grades.append(grade)
        y = y + 1
    calculate()

def calculate():
    total= 0
    for element in grades:
        if element == "A+":
            total = total + 4.0
        elif element == "A":
            total = total + 4.0
        elif element == "A-":
            total = total + 3.7
        elif element == "B+":
            total = total + 3.3
        elif element == "B":
            total = total + 3.0
        elif element == "B-":
            total = total + 2.7
        elif element == "C+":
            total = total + 2.3
        elif element == "C":
            total = total + 2.0
        elif element == "C-":
            total = total + 1.7
        elif element == "D":
            total = total + 1.0
    gpa = total / 6
    print(gpa)


collect()

It all works the way it should, but if someone more experienced could tell me a better way to work with the class names and the grade associated and if there is a more efficient way to calculate the grades with some kind of dictionary or some other way, that would be appreciated.

\$\endgroup\$
3
\$\begingroup\$

Avoid global variables

There's no good reason for the variables classes and grades to be defined and manipulated in global scope. For example, it would be better to pass grades into the calculate function as a parameter.

Consider a table-driven solution

The long if-else chain is tedious. You could instead use a dictionary to map the grade notes to scores:

score_map = {
    'A': 4,
    'C': 2,
    'C-': 1.7,
    'D': 1,
    # ... and so on
}
total = 0
for grade in grades:
    total += score_map[grade]

This approach also makes it easy to use a list-comprehension that's more compact than a for loop:

return sum(score_map[grade] for grade in grades) / 6

Usability

Making the user enter the class names seems rather pointless. The program simply prints them back, without doing anything interesting with them.

Style

The parentheses are redundant here:

while (y <= 5):

Instead of y = y + 1 you can use the augmented assignment form y += 1.

Python has a style guide called PEP8 with a utility to spot such issues.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.