Crazycops
Crazycops

Reputation: 31

If statement to repeat for every occurence

I have a list with different course names followed by a comma then followed by the grade.

courses = ['COMP 1000,A+', "MATH 1000,A+", 'SCIE1000,B+"]

For every time a grade occurs in the list, I change it to the grade point value and add it to a different list. Then from there I calculate the GPA by finding the average. I am using the following code for that:

if any("A+" in n for n in courses):
    grades.append(4.30)
if any("B+" in n for n in courses):
    grades.append(3.30)

This is working fine for lists where each grade is repeated once but for the courses list above there are two A+'s however 4.30 is only being added once. Is there a way to add 4.30 to the new list for every time a grade is in a list?

Thanks

Upvotes: 3

Views: 78

Answers (5)

HannahEslinger
HannahEslinger

Reputation: 59

There are some good answers here but none tell you why what you current have doesn't work:

The problem lies in the your use of any. The any function takes in a list of Booleans and returns true if at least one value in the list is true.

>>> any([True, True])
True
>>> any([True, False])
True
>>> any([False, False])
False

No matter how many Trues there are in the list, only a single boolean is returned, and your if statement will only run once. Thus, even if there are two "A+"s in your list, only one append is preformed.

The closest thing to what you where trying to achieve with your any function (that I can think of) would be list comprehension with a condition:

>>> courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
>>> [n for n in courses if "A+" in n]
['COMP 1000,A+', 'MATH 1000,A+']

Here, items that don't met the condition "A+" in n are not part if the new array. This would make your code look like this:

for i in [n for n in courses if "A+" in n]:
    grades.append(4.30)

that said, I wouldn't recommend doing that. There are other solutions that are cleaner and more readable, like Ismeal's solution, or even something as simple as this:

courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]
grades= []
for course in courses:
    if "A+" in course:
       grades.append("4.30")
...

Bonus Pro tip! Consider the possibility that in of the courses might be BIO,A+. which would pass the if statement. if "B" in course. It might be worth separating the course name and grade.

 >>> "Bio,A+".split(",")
 ['Bio', 'A+']
 >>> "Bio,A+".split(",")[1]
 'A+'

;) happy coding!

Upvotes: 2

Adam Smith
Adam Smith

Reputation: 54183

The existing answers are great, but I wanted to show a more object-oriented approach in case that's edifying. Personally I prefer functional style, but OO is much of what's being taught now.

from decimal import Decimal  # for precise decimals instead of float math

class Course:
    def __init__(self, name, lettergrade):
        self.name = name
        self.lettergrade = lettergrade

    @classmethod
    def from_string(cls, s):
        name, lettergrade = s.split(',')
        return cls(name.strip(), lettergrade.strip())

    @property
    def gradepoint(self):
        mapping = {
            "A+": Decimal('4.3'),
            "A": Decimal('4'),
            "A-": Decimal('3.7'),
            "B+": Decimal('3.3'),
            "B": Decimal('3'),
            ... # etc
        }

        return mapping.get(self.lettergrade)

# Read the input into `courses`, then:

courses = [Course.from_string(c) for c in courses]
grades = [c.gradepoint for c in courses]

from statistics import mean

avg = mean(grades)  # gives a Decimal equal to your mean grade

Upvotes: 0

wjandrea
wjandrea

Reputation: 32954

You're going about this the wrong way. Loop over the courses, split on the comma, and look up the grade-to-grade-point conversion in a dict (the equivalent of a case statement in other languages).

courses = ['COMP 1000,A+', 'MATH 1000,A+', 'SCIE1000,B+']
grades = []

grade_to_grade_point = {
    "A+": 4.30,
    "B+": 3.30,
    # ...
    }
for course in courses:
    course_name, grade = course.split(',')
    grades.append(grade_to_grade_point[grade])

print(grades)  # -> [4.3, 4.3, 3.3]

Or as a list comprehension:

grades = [grade_to_grade_point[c.split(',')[1]] for c in courses]

Upvotes: 3

marcos
marcos

Reputation: 4510

If you want it in one line you can use this:

courses = ['COMP 1000,A+', "MATH 1000,A+", "SCIE1000,B+"]
points = {'A+': 4.30, 'B+': 3.30}
grades = [value for grade, value in points.items() for course in courses if grade in course]
print(grades)

>>> [4.3, 4.3, 3.3]

Upvotes: 0

Ismael Padilla
Ismael Padilla

Reputation: 5566

What about using a list comprehension?

courses = ["COMP 1000,A+", "MATH 1000,A+", "SCIE1000,B+"]

def func(x):
    if "A+" in x:
       return 4.30
    elif "B+" in x:
        return 3.30
    # add other cases

grades = [func(x) for x in courses]

print(grades) # [4.3, 4.3, 3.3]

Upvotes: 1

Related Questions