Reputation: 31
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
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 True
s 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
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
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
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
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