Im trying to return the 'students' grades according to what they got on python. I used a bunch of elif statements but i dont feel like this is efficient. I was wondering if there are any other ways i can present this as? possibly smaller. Ive attempted using for loops and dictionaries, but im not getting it, maybe cuz i dont understand dictionaries well loll
def grade_select(grade):
if grade < 40: return "D-"
elif grade <= 40 and grade < 45: return "D"
elif grade <= 45 and grade < 50: return "D "
elif grade <= 50 and grade < 55: return "C-"
elif grade <= 55 and grade < 60: return "C"
elif grade <= 60 and grade < 65: return "C "
elif grade <= 65 and grade < 70: return "B-"
elif grade <= 70 and grade < 75: return "B"
elif grade <= 75 and grade < 80: return "B "
elif grade <= 80 and grade < 85: return "A-"
elif grade <= 85 and grade < 90: return "A"
elif grade >= 90: return "A "
CodePudding user response:
since you return when a condition is matched, you do not need to use elif
just if
.
moreover, the previous condition eliminates the need of checking if the value is "between".
def grade_select(grade):
if grade < 40: return "D-"
if grade < 45: return "D"
if grade < 50: return "D "
if grade < 55: return "C-"
if grade < 60: return "C"
if grade < 65: return "C "
if grade < 70: return "B-"
if grade < 75: return "B"
if grade < 80: return "B "
if grade < 85: return "A-"
if grade < 90: return "A"
return "A "
an alternative would be to declare a dictionary and calculate where the grade fits.
grades = { 40: "D-", 45: "D", 50: "D ", 55: "C-", 60: "C", 65: "C ", 70: "B-", 75: "B", 80: "B ", 85: "A-", 90: "A", 100: "A " }
def grade_select(grade):
grade = (grade // 5 * 5) 5
if grade < 40:
grade = 40
elif grade > 90:
grade = 100
return grades[grade]
CodePudding user response:
You can use a dictionary to store the range and it's according grade value:
def grade_select(grade):
dct = {
range(0, 40): "D-",
range(40, 45): "D",
range(45, 50): "D ",
...
range(90, 100 1): "A "
}
dct = {g: m for r, m in dct.items() for g in r}
return dct[grade]
CodePudding user response:
Well, your condition is kinda weird, because
elif grade <= 40 and grade < 50
has no sense (if grade <= 40 then grade < 50 of course)
But I think you wanna write something like this:
if 40 <= grade < 50:
pass
You can use syntax above, it could make it a little bit better. Also, you can check this article
CodePudding user response:
I guess using dictionary is the best way
def grade_select(grade):
d = {
'D-':range(0,40),
'D':range(45,50),
'D ':range(50,55),
'C-':range(55,60) #, etc.
}
return [k for k,v in d.items() if grade in v]
CodePudding user response:
Here's the fastest version that calculates an index based on the grade value. This method only works if your grade ranges are all five wide.
_lettergrades = ['D-', 'D', 'D ', 'C-', 'C', 'C ', 'B-', 'B', 'B ', 'A-', 'A', 'A ']
def grade_select(grade):
return _lettergrades[(max(min(grade, 90), 35) - 35) // 5]
If your ranges weren't consistently five wide you could use bisect.bisect_right
to get an index for the letter grade. The search uses bisection, which should be faster than a linear search. (The lists _thresholds
and _lettergrades
are global to avoid recreating them for every call to grade_select()
.)
from bisect import bisect_right
_thresholds = [40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90]
_lettergrades = ['D-', 'D', 'D ', 'C-', 'C', 'C ', 'B-', 'B', 'B ', 'A-', 'A', 'A ']
def grade_select(grade):
return _lettergrades[bisect_right(_thresholds, grade)]
Note: I doubt speed matters as much as clarity here. For clarity I like Paulo Pereira's answer best.