patternpythonMinor
Validating and averaging student grades
Viewed 0 times
gradesstudentaveragingvalidatingand
Problem
I have myself a little challenge tonight. I've tried to come up with the shortest code for the problem below (the code is pretty self explanatory, except
A - 90-100%
B - 80-89%
C - 70-79%
D - 60-69%
F - Below 60%
The code has to be PEP8 complient and no imports (std included) are allowed. Tell me if you can shorten the code further.
determinGrade there which follows the ruleA - 90-100%
B - 80-89%
C - 70-79%
D - 60-69%
F - Below 60%
The code has to be PEP8 complient and no imports (std included) are allowed. Tell me if you can shorten the code further.
isValidScore = lambda n: 0 <= n <= 100
calcAverage = lambda *args: sum(args)/len(args)
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, (min(s, 99)/10)-5)]
def getValidScore():
while True:
try:
s = int(raw_input('Input score: '))
if isValidScore(s):
return s
except ValueError:
pass
print('Score has to be an integer in the range 0 to 100')
if __name__ == "__main__":
scores = [getValidScore() for _ in range(5)]
print('The scores are: ' + str(scores))
print('The average is: ' + str(calcAverage(*scores)))
print('The grade is: ' + determinGrade(calcAverage(*scores)))Solution
Although this passes the
this is not PEP8 compliant:
If you convert the lambda expressions to
Also, these statements are a bit tightly packed for my taste:
Would have been better this way, but PEP8 does not require it:
In this last statement, there are some redundant parentheses, this is equivalent:
Instead of the
Last but not least, beware that in Python 3,
Suggested implementation
Putting the above suggestions together:
pep8 tool as of version 1.5.5,this is not PEP8 compliant:
- Function names should be lowercase, with words separated by underscores as necessary to improve readability.
- Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.
If you convert the lambda expressions to
def statements, the result will be longer, but better.Also, these statements are a bit tightly packed for my taste:
calcAverage = lambda *args: sum(args)/len(args)
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, (min(s, 99)/10)-5)]Would have been better this way, but PEP8 does not require it:
calcAverage = lambda *args: sum(args) / len(args)
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, (min(s, 99) / 10) - 5)]In this last statement, there are some redundant parentheses, this is equivalent:
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, min(s, 99) / 10 - 5)]Instead of the
min hack for the value of 100, how about this way:determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A', 'A'][max(0, s / 10 - 5)]Last but not least, beware that in Python 3,
27 / 10 will give you 2.7 instead of 2 as in Python 2. As such, the determinGrade will try to use a float as the list index, and your script will break. Adopting Python 3 is probably only a matter of time, so it's good to be prepare for that, and use // to ensure that you will get an integer index:determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A', 'A'][max(0, s // 10 - 5)]Suggested implementation
Putting the above suggestions together:
def is_valid_score(n):
return 0 <= n <= 100
def calc_average(*args):
return sum(args) / len(args)
def determine_grade(s):
return ['F', 'D', 'C', 'B', 'A', 'A'][max(0, s // 10 - 5)]
def get_valid_score():
while True:
try:
s = int(raw_input('Input score: '))
if is_valid_score(s):
return s
except ValueError:
pass
print('Score has to be an integer in the range 0 to 100')
if __name__ == "__main__":
scores = [get_valid_score() for _ in range(5)]
print('The scores are: ' + str(scores))
print('The average is: ' + str(calc_average(*scores)))
print('The grade is: ' + determine_grade(calc_average(*scores)))Code Snippets
calcAverage = lambda *args: sum(args)/len(args)
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, (min(s, 99)/10)-5)]calcAverage = lambda *args: sum(args) / len(args)
determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, (min(s, 99) / 10) - 5)]determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A'][max(0, min(s, 99) / 10 - 5)]determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A', 'A'][max(0, s / 10 - 5)]determinGrade = lambda s: ['F', 'D', 'C', 'B', 'A', 'A'][max(0, s // 10 - 5)]Context
StackExchange Code Review Q#66821, answer score: 4
Revisions (0)
No revisions yet.