The following program should do as you asked. There are several lines that are commented out with the #
character. You may uncomment those lines if you wish to see the value of the variable referenced in the call to the debug
function. Please take time to study the code so that you understand how and why it works.
import pprint
import sys
RANGE = range(0, 101)
GRADE = {70: 'First', 60: 'Second Upper',
50: 'Second Lower', 45: 'Third',
40: 'Pass', 0: 'Fail'}
MARKS = -1, 0, 1, 49, 60, 71, 100, 101
def main():
"""Grade hardcoded marks and grade marks entered by the user."""
# debug('MARKS')
grade_all(MARKS)
grade_all(get_marks())
print('Goodbye!')
def grade_all(marks):
"""Take an iterable of marks and grade each one individually."""
for mark in marks:
# debug('mark')
if mark in RANGE:
print(mark, 'gets a grade of', grade_one(mark))
else:
print(mark, 'is not a valid mark')
def grade_one(mark):
"""Find the correct grade for a mark while checking for errors."""
# debug('RANGE')
if mark in RANGE:
for score, grade in sorted(GRADE.items(), reverse=True):
if mark >= score:
return grade
raise ValueError(mark)
def get_marks():
"""Create a generator yielding marks until the user is finished."""
while True:
try:
text = input('Mark: ')
except EOFError:
sys.exit()
else:
# debug('text')
if text.upper() == 'Q':
break
try:
mark = round(float(text))
except ValueError:
print('Please enter a mark')
else:
# debug('mark')
if mark in RANGE:
yield mark
else:
print('Marks must be in', RANGE)
def debug(name):
"""Take the name of a variable and report its current status."""
frame, (head, *tail) = sys._getframe(1), name.split('.')
for scope, space in ('local', frame.f_locals), ('global', frame.f_globals):
if head in space:
value = space[head]
break
else:
raise NameError('name {!r} is not defined'.format(head))
for attr in tail:
value = getattr(value, attr)
print('{} {} {} = {}'.format(
scope, type(value).__name__, name, pprint.pformat(value)), flush=True)
if __name__ == '__main__':
main()
solved Issues with a college assignment using Python